namespace and extern 'C' compilation errors - c

I have tried to google the errors but to no avail. Maybe I am searching in the wrong direction.
I am trying to compile a file but when i tired to compiled it, the compiler gave me these errors:
C2059 syntax error: ';'
C2059 syntax error: '}'
C2061 syntax error: identifier 'namespace_name'
C2449 syntax error: found '{' at file scope (missing header?)
In my code.c file:
#ifndef myclass_c
#define myclass_c
#include "classA.h"
#include "classB.h"
#include "conversionLib.h" // no namespace is being used here
namespace namespace_name {
// ... generated codes in C....
}
#endif
In classA.h and in classB.h:
#ifndef myclassA_h // myClassB_h if in classB
#define myclassA_h // myClassB_h if in classB
#include "classC.h" // both classA and classB include classC.h
namespace namespace_name {
#ifdef __cplusplus
extern "C" {
#endif
// ... generated codes in C....
#ifdef __cplusplus
}
#endif
}
#endif
and in classC.h (same for classD.h)
#ifndef myclassC_h // myclassD.h for classD.h
#define myclassC_h // myclassD.h for classD.h
#include "classD.h" // no includes in classD.h
namespace namespace_name {
#ifdef __cplusplus
extern "C" {
#endif
// ... generated codes in C....
#ifdef __cplusplus
}
#endif
}
#endif
what am i doing wrong? or have i missed out something?
Any suggestion would be greatly appreciated.
I apologized if this question/format is confusing.
Thanks in advance

The main problem seems to be, that you use c++ syntax in a .c file.
C does not support namespaces!
It does not make much sense to put a extern "C" function into an namespace. in C++ the compiler does something called 'name mangeling' it actually puts the name space (e.g. the class name, the namespace) and additional information (like function or template parameter) of an identifier into its symbol name that is the input to the linker.
extern "C" tells the C++ Compiler not to do so. so you lose the binding to the surrounding namespace (as well as the possibilities to overload the function).
It may be a nice thought to put the functions in a special namespace if they are included from C++ but on the other hand mostly in C namespaces are build y using a special prefix to the function name. so in C++ you end up with the explicit c++ name space and the implicit function prefix name space.
If you still want a namespace in c++ around your C-Functions you have to include the namespace definition into your #ifdef __cplusplus blocks. (but i do not even know if this is allowed by the C++ standard)

Related

conflicting declaration of C function With #ifdef __cplusplus

I failed to define overloading functions with error message of error: conflicting declaration of C function if enclosing by #ifdef __cplusplus blocks.
Below is a simple code for an easy view. This piece of code worked fine without #ifdef __cplusplus blocks.
However, my project code does need #ifdef __cplusplus as it involves combination of C and C++ codes.
Command lines after #ifdef __cplusplus block should be C++, why did it fail to define the overloading function? How to fix this problem with presence of #ifdef __cplusplus blocks?
#include <iostream>
using namespace std;
#ifdef __cplusplus
extern "C"
{
#endif
int add(int x)
{
return x;
}
int add(int x, int y)
{
return x + y;
}
int main() {
// cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!!
int X = add(2);
int Z = add(8,2);
cout <<X<<" "<<Z<<endl;
return 0;
}
#ifdef __cplusplus
}
#endif
Command lines after #ifdef __cplusplus block should be C++
First of all, I believe you have a misconception of #ifdef __cplusplus, this macro only checks if your compiler is a C++ compiler or not.
You rather need focus on extern "C" {}. This block of code explicitly tells your compiler, that codes inside this block must be in C language(not C++).
This is important since C and C++ have different mechanisms of storing and calling functions from binary. (Called name mangling). Better to say, C and C++ binaries are not compatible. So extern "C" will tell your compiler that your functions C codes, and those function names are not mangled.
So #ifdef __cplusplus checks if your code is C or C++; if your code is in C++, insert extern "C" { that tells your compiler that those codes in this block are C code.
And since function overloading is not a part of C language, your compiler will cause an error inside that block. (This matters with name mangling).
But this macro is mostly used in header files, not source files. Because the purpose of this macro is to enable your code to be included in both C and C++ code, but source files cannot be and must not be included by another source.

Including c files in .msg files (Veins)

I'm trying to implement a BSM in Veins 4.4. In order to reach this purpose I would like to import my libasn which are C files (.c and .h ) in the WaveShortMessage.msg in order to populate the BSM.
I tried to import them as follows:
#include "veins/asn/BasicSafetyMessage.h"
#include <veins/asn/BasicSafetyMessage.h>
3.
extern "C" {
#include "veins/asn/BasicSafetyMessage.h"
};
4.
#ifdef __cplusplus
extern "C" {
#endif
#include "veins/asn/BasicSafetyMessage.h"
#ifdef __cplusplus
}
#endif
but it doesn't work. It always returns an error.
Could you suggest the right way to do it? Thanks a lot
Using a C or C++ code in the message's definition in OMNeT++ is described in details in OMNeT++ Simulation Manual, chapter 6.5.
You should use cplusplus keyword, an example for C code in BasicSafetyMessage.h:
cplusplus {{
extern "C" {
#include "veins/asn/BasicSafetyMessage.h"
};
}}

C - define, #include, and redefine

I have a driver which is known to compile on somebody else's machine, however, it's not on mine (a toolchain/compiler difference?). I'm getting error: implicit declaration of function '__REG' [-Werror=implicit-function-declaration]. Here's the code which is causing it:
enum {
#define __REG(a,b2,b1,c,d,e,f) a,
#include "mycodec-i2c.h"
#undef __REG
};
And then later on in the code...
static const mycodec_reg_t mycodec_data[]=
{
#define __REG(a,b2,b1,c,d,e,f) c,
#include "mycodec-i2c.h"
#undef __REG
};
Is that really legal to do in C? How do I get around it?
The header file contains a whole bunch of register definitions.

weird c function syntax

I know my C up to this point. I was looking at the source files of PHP I downloaded, and I saw this strange syntax:
PHPAPI int php_printf(const char *format, ...)
{
// code...
}
What does the PHPAPI do before the return type int? I've tried searching all over and I can't understand what this means. Is it a second return type? It can't be because the function does return an int. Maybe it extends to some other struct declared in a header file?
The hard way:
Go to the makefile and add in the line that compiles the sources: -E, by doing so you will see the source cose after the preprocessing phase.
The easy way:
Search all the project for PHPAPI:
find it in php.h:
#ifdef PHP_WIN32
#include "win95nt.h"
# ifdef PHP_EXPORTS
# define PHPAPI __declspec(dllexport)
# else
# define PHPAPI __declspec(dllimport)
# endif
#define PHP_DIR_SEPARATOR '\\'
#else
#define PHPAPI
#define THREAD_LS
#define PHP_DIR_SEPARATOR '/'
#endif
Now what you need to know is what is __declspec(dllexport) and what is __declspec(dllimport)
In the SO thread- What is __declspec and when do I need to use it?
see Alexander Gessler answer:
The canonical examples are __declspec(dllimport) and
__declspec(dllexport), which instruct the linker to import and
export (respectively) a symbol from or to a DLL.
// header
__declspec(dllimport) void foo();
// code - this calls foo() somewhere in a DLL
foo();
(__declspec(..) just wraps up Microsoft's specific stuff - to
achieve compatibility, one would usually wrap it away with macros)

extern "C" error #2040: expected an identifier

I still struggling to compile a C console application, the compiling procedure still failing with the error below:
"Main.c", line 51: error #2040: expected an identifier
extern "C" void TreatReceivedSignal( int NoSignal ) ;
^
1 error detected in the compilation of "Main.c".
gmake: *** [Main.o] Error 2
below the declaration of the extern method on the C code :
extern "C" void TreatReceivedSignal( int NoSignal ) ;
I am using HP-UX aCC compiler [HP C/aC++ B3910B A.06.26], also I switched on the compilation flag -Ae to enable C99 support.
Seems that the compiler cannot recognize the 'extern "C"' as C reserved word, may some other compilation flag need to be set.
Any idea please that can solve this kind of issue?
Thank you very much in advance.
Regards
The extern "C" construct is a C++ specific thing, it can't be used in C. And the compiler treats your source file as a C source file since it has the extension .c.
The most common thing to do is to use the preprocessor to conditionally add this for C++ compilations:
#ifdef __cplusplus
extern "C" {
#endif
/* Standard C prototypes */
#ifdef __cplusplus
}
#endif

Resources