top button
Flag Notify
    Connect to us
      Site Registration

Site Registration

Warning for incompatible functions declared 'extern "C"'?

+1 vote
601 views

I have an oversight in my code where I'm declaring & defining a function
with C-linkage, though it's not possible.

Example snippet:

#ifdef __cplusplus
extern "C"
{
#endif

// ... some functions which are compatible with C linkage

// Intended to be a helper function not exposed from library
std::string GetEngineVersion()
{
 // ...
}

#ifdef __cplusplus
}
#endif

Obviously the GetEngineVersion function cannot have C linkage because it returns a C++ class.

My question is: does GCC have a warning for this scenario? Specifically, can it warn when something is declared extern "C" that's incompatible with C linkage?

I compile with the following warning flags and I didn't get a warning:

-Wall -Wunused-parameter -Wextra -Weffc++ -Wctor-dtor-privacy
-Wnon-virtual-dtor -Wreorder -Wold-style-cast -Woverloaded-virtual
-Werror

Incidentally, when I compile the same code in VS2013 I get this warning:

warning C4190: 'GetEngineVersion' has C-linkage specified, but returns UDT 'std::basic_string' which is incompatible with C
posted Jul 23, 2014 by Honey

Share this question
Facebook Share Button Twitter Share Button LinkedIn Share Button

1 Answer

+1 vote

That is valid C++ code. C linkage doesn't mean the function has to actually be usable from C.

You can also declare functions with C linkage that take reference parameters or throw exceptions.

My question is: does GCC have a warning for this scenario? Specifically, can it warn when something is declared extern "C" that's incompatible with C linkage?

No, there is no such warning as far as I know.

Such a warning doesn't seem unreasonable, since usually (not not always) you want functions with C language linkage to be callable from C.

answer Jul 24, 2014 by Luv Kumar
Similar Questions
+2 votes

I tried using -Wzero-as-null-pointer-constant in a C++ program, but I got warnings in some C headers, even though they are wrapped in extern "C" blocks.

Since there is no nullptr in C, wouldn't it make more sense to disable the warning within those blocks? Is there some option that I'm missing?

+7 votes

In lot of C++ code in my company I see extern C code something like

extern "C"
{
    int sum(int x, int y)
    {
        return x+y;
    }
}

Please explain the significance of this?

0 votes

is it possible to add a private extension to the core language (C/C++) by writing a gcc plugin?

The extension in mind is something like this

[variable_definitions;]

Later I want this be possible also inside statement headers, for example

for ([double d = 1.0; bool f = false;] size_t i = 0; i < vec.size(); ++i)
 ...

The scope of the so-defined variables shall be the same scope they are in, ie. in the for-loop case just the scope of the for-loop itself, much like the case with i.

+1 vote

I am building a shared library which will be distributed to clients in binary form only. I am attempting to make the same binary run on as many Linux variants as possible, and so when I build it I specify the
options -shared and -fPIC. As part of the effort of making the library as independent as possible, I also link both the C and C++ standard libraries statically into the final shared library. I want to do this because I use
C++11 features internally, and I don't want to force the users of my library to have a C++11 compiler handy.

When doing this, do I need to build libstdc++ and libgcc from source with -fPIC as well? Or is it okay to link with the static versions of these libraries that are provided in my Ubuntu 13.04 gcc package?

To clarify, no exceptions are thrown over library boundaries; all exceptions used internally in the library are caught and processed behind the scenes. None of them ever reach the client code, as the client communicates with the library using a plain C interface.

My exact build flags are as follows:

g++ -fvisibility=hidden -fvisibility-inlines-hidden -static-libstdc++ -static-libgcc -s -DNDEBUG -std=c++11 -Wall -shared -fPIC -o libtest.so test.cpp -lpthread -O2

+1 vote
#include<stdio.h>
void fun(static int a);
int main(void)
{
   static int z=0;

   fun(z);

   return 0;
}

void fun(static int a)
{
   printf("%d",a);
}
...