-1

Please consider the following code:

Test2.h:

#ifndef ABCD
#define ABCD

#ifdef __cplusplus
extern "C" {
#endif

void Foo();

#ifdef __cplusplus
}
#endif
#endif // ABCD

Test2.cpp

#include "StdAfx.h"
#include "Test2.h"

inline void Foo()
{
}

Test.cpp:

#include "stdafx.h"
#include "Test2.h"

int _tmain(int argc, _TCHAR* argv[])
{
    Foo();
    return 0;
}

When I compile this code I get LNK2019 error (Unresolved external symbol _Foo). I can solve it in two ways.

  1. Remove the inline keyword.
  2. Add extern to the function declaration.

Assuming I want this function inline, why do I have to add extern to the declaration?

I use VS2008.

Thanks.

Tsikon
  • 324
  • 1
  • 3
  • 14
  • 1
    C or C++? Inline functions are **very** different between the two. – Angew is no longer proud of SO Jan 07 '18 at 16:25
  • You could also move the function definition to the header. – SoronelHaetir Jan 07 '18 at 16:27
  • How do you compile and link the code? What is the link command line? – Jonathan Leffler Jan 07 '18 at 16:28
  • `inline` is not the only problem. You declared `extern "C"` function and then define C++ function. Additionally `Foo()` in C equals to `Foo(...)` in C++. – 273K Jan 07 '18 at 16:34
  • @S.M. Since `Test2.cpp` includes `Test2.h`, it will see the `extern "C'` declaration, and apply C language linkage to `Foo` correctly, that's not the issue. – Angew is no longer proud of SO Jan 07 '18 at 16:39
  • 1
    What is the purpose of your `inline` specifier? In C++ it mostly means that the ODR does not apply. But you define `Foo` in the source file, so you do not need to care about ODR in this case anyway. – Daniel Langr Jan 07 '18 at 16:41
  • 1
    As for _inlining_, a compiler cannot inline function, if its definition is not in a translation unit. Which usually means that the definition must be in a header file. – Daniel Langr Jan 07 '18 at 16:51
  • @DanielLangr The purpose of the inline is exactly what is it - "Replace those function definition wherever those are being called". What you're saying is, moving the definition to the header or using extern in the declaration is the same? – Tsikon Jan 07 '18 at 17:39
  • Why do you use `extern "C"`? –  Jan 07 '18 at 17:42
  • @JonathanLeffler Why on earth do I deserve a downvote for what you think are irrelevant tags (With all do respect)? I partially agree on the WINAPI because this code is relevant not only for windows but why does C tag is irrelevant? – Tsikon Jan 07 '18 at 17:44
  • Not my downvote. The code is C++, in C++ source files. The rules on online functions are different in C and C++. Using `_tmain()` places you firmly in the world of Windows. It has no meaning anywhere else. We can debate which Windows tagnto use, but it is purely Windows C++ code in the Question; no C code. – Jonathan Leffler Jan 07 '18 at 17:46
  • @JonathanLeffler Got it. Thanks – Tsikon Jan 07 '18 at 17:56
  • @manni66 I need faster execution time for those functions. – Tsikon Jan 07 '18 at 18:07
  • @SoronelHaetir I wish to keep the definitions hidden from the user but still use it as inline for performance. Is that possible by using extern on the function declaration? – Tsikon Jan 07 '18 at 18:11
  • Inline means the programmers using it can see the code. If you don’t want the code exposed, don’t make it inline. – Jonathan Leffler Jan 07 '18 at 18:23
  • @JonathanLeffler Alright, so what's the meaning of adding extern to the function declaration? Does the compiler ignores the inlining? – Tsikon Jan 07 '18 at 18:30
  • Please search on SO (or the wider web) for the information. There will be answers aplenty for C++ (and for C, but there are differences in detail between the two languages, compounded by differences in the way GCC has handled them historically). – Jonathan Leffler Jan 07 '18 at 18:40
  • _I need faster execution time for those functions_ you think `extern "C"` executes faster? That’s bluntly wrong. –  Jan 07 '18 at 19:01
  • You're right @manni66 I meant faster execution on the inlining. extern "C" is for compiling with C compiler also. – Tsikon Jan 07 '18 at 19:03
  • I don't know what `inline` specifier means in C. In C++, it does not force a compiler to inline function code (C++ compiler may decide not to inline a function marked `inline` and vice versa). See, e.g., this answer: https://stackoverflow.com/questions/1759300/when-should-i-write-the-keyword-inline-for-a-function-method. There is also discussion about `extern`. – Daniel Langr Jan 07 '18 at 19:16
  • Eureka, I finally see what you're trying to achieve. You want a C++ function inlined into C code. I don't think it's possible (correct me if I am wrong). Inlining is _something like_ taking the function body and putting it in the place of a function call. So, effectively, you are placing C++ code into C code. How could a C compiler then compile such a code? – Daniel Langr Jan 07 '18 at 19:45

1 Answers1

2

C++11 Standard Paragraph 3.2.3:

An inline function shall be defined in every translation unit in which it is odr-used.

You have 2 translation units, first made from Test2.cpp...:

// ... code expanded from including "StdAfx.h"

extern "C" { void Foo(); }

inline void Foo() { }

...and second made from Test.cpp:

// ... code expanded from including "StdAfx.h"

extern "C" { void Foo(); }

int _tmain(int argc, _TCHAR* argv[])
{
    Foo();
    return 0;
}

In the second TU, the definition of Foo is missing.

Why don't you simply put the definition of Foo into the header file? Compiler cannot inline its code if it does not see it.

Daniel Langr
  • 22,196
  • 3
  • 50
  • 93
  • Make sense.. I'm still searching for an answer about the extern issue.. I guess I need to dig deeper. Thanks for spending time to help me. – Tsikon Jan 07 '18 at 21:56
  • In C++, the `extern` specifier results in external linkage when used with function declaration. However, function declarations have in most cases external linkage by default, so the `extern` keyword is then superfluous. I am not sure what `extern` means if the function declaration is inside `extern "C"` block. – Daniel Langr Jan 08 '18 at 09:04