2015-11-04 17 views
0

下面的代码不违反一个定义规则,但它给了意想不到的结果:C++内联函数,并具有相同名称的外部函数给出一个意想不到的结果

Test.hpp

class Test 
{ 
    public: 
     int test(); 
}; 

Test1.cpp

#include "Test.hpp" 

int Test::test() 
{ 
    return 1; 
} 

int test1() // expected to return 1 
{ 
    Test a = Test(); 
    return a.test(); 
} 

测试2.cpp

#include "Test.hpp" 

inline int Test::test() // doesn't violate ODR 
{ 
    return 99; 
} 

int test2() // expected to return 99 
{ 
    Test a = Test(); 
    return a.test(); 
} 

的main.cpp

#include <iostream> 

int test1(); 
int test2(); 

int main() 
{ 
    std::cout << test1() << std::endl; 
    std::cout << test2() << std::endl; 
} 

我期待它打印 “1 99”,但它总是打印 “1 1”。

关于Test :: test的两个定义,由于它们中的一个是内联定义,所以它也不违反One Definition Rule。

所以这个方案是有效的,但它不是打印出预期的结果...

有什么不对这个计划?还是我误解了一些关于ODR规则的东西? (对C++标准的引用会很有帮助)。

+1

'关于测试::测试的两个定义,因为他们中的一个是内联函数,它不违反ODR'你从哪里得到这个理念? – bolov

+0

嗯,我认为它没有违反ODR,因为在C++规范的ODR部分中没有提到这个问题。 “如果具有外部链接的功能在一个翻译单元中声明为内联,则应在其出现的所有翻译单元中声明为内联;不需要诊断。”在函数说明符部分提到,它不涉及ODR。 – SHH

回答

3

您不能将该功能定义为inline和非inline

如果具有外部链接的功能 在一个翻译单元中声明的内联,应当内嵌在其中出现所有翻译单元声明; 不需要诊断。

([dcl.fct.spec/4)

+0

感谢您的回答。但是您提到的声明并未在规范的ODR部分中说明。那么我可以说我提供的代码不违反ODR吗? (它违反了函数说明符规则,但不是ODR) – SHH

+0

@SHH我不能说它是否有效。 ODR的措辞具有“非内联功能”。因此它隐含地假设一个函数不能既是内联也是非内联的;它必须是一个或另一个。当您试图声明同时使用内联和非内联函数时,ODR甚至没有意义。 – Brian

相关问题