Undefined symbols for constexpr function

前端 未结 3 936
[愿得一人]
[愿得一人] 2021-01-04 02:16

When I attempt compiling the following code I get a linker error: Undefined symbols for architecture x86_64: \"Foo()\", referenced from: _main in main.o using L

相关标签:
3条回答
  • 2021-01-04 03:06

    Why does declaring the function constexpr cause a linker error?

    That is because constexpr functions are implicitly inline. Per Paragraph 7.1.5/2 of the C++11 Standard:

    A constexpr specifier used in the declaration of a function that is not a constructor declares that function to be a constexpr function. Similarly, a constexpr specifier used in a constructor declaration declares that constructor to be a constexpr constructor. constexpr functions and constexpr constructors are implicitly inline (7.1.2).

    Per Paragraph 7.1.2/4, then:

    An inline function shall be defined in every translation unit in which it is odr-used and shall have exactly the same definition in every case (3.2). [...]

    0 讨论(0)
  • 2021-01-04 03:13

    It's an interesting question. As Andy Prowl, constexpr makes the function inline, which means that there must be a definition of it in every translation unit which uses it; I would have expected an error from the compiler. (Actually, if I read §3.2/5 correctly, a diagnostic is required if you use the function and there is no definition.)

    As to why const has different behavior: you can't mark a non-menber function const. If you write const int Foo();, it is not the function which is const, but the type it returns (except that if the return type is not a class type, cv-qualifiers are ignored, so this is really the same as int Foo();).

    0 讨论(0)
  • 2021-01-04 03:14

    The body of a constexpr function must be visible at every point where it's used. In your case you have to move Foo()'s code to test.hpp.

    For instance, consider this code in main.cpp:

    constexpr int Foo(); 
    
    int main() {
      static_assert(Foo() == 42, "Ops");
    }
    

    where Foo() is defined in test.cpp. How the compiler is supposed to check the static_assert condition while processing main.cpp if it cannot see that Foo() does return 42. That's impossible. The whole point of constexpr functions is that the compiler can "call" them at compile time and for this to happen it must see the code.

    Therefore, this compiles fine:

    constexpr int Foo() { return 42; }
    
    int main() {
      static_assert(Foo() == 42, "Ops");
    }
    
    0 讨论(0)
提交回复
热议问题