I want to have a global names variable, which looks like that
char* names[NAMES_CAP];
int names_len = 0;
And I want every one who links to this library to be able to add an item to this list.
It's easy to do that from main.
int main(int argc,char**argv) {
names[names_len++] = "new name";
names[names_len++] = "new name 2";
}
but what if I want to stack up two libraries? (ie, my library, libnames holds the global variable. And if someone links to libnameuser who uses libnames, it will automatically add all names defined in libnameuser to the names array in libnames.
Is there any way to do that?
In C++, I can insert the names[names_len++] = "..." to the constructor of a global object, and it must be called. But can I do that with plain C?
If you are using gcc you can use the constructor attribute __attribute__((constructor)) to get the same effect. This is however non-standard C.
I would however recommend against this pattern since there is no control of ordering of any function run before main. I would rather find a nice method of hooking in all the "constructor" functions after main has started running.
Update: Refer to https://stackoverflow.com/a/2390626/270788 for updated version of this answer.
Below is a pre-processor abstration to support C static initializer functions with GCC and MSVC. The GCC version will also work with LLVM CC, maybe some other compilers as well.
The MSVC version works by placing a ptr to the static initializer function in a special section that is processed by the application or DLL startup code.
#if defined(__GNUC__)
#define INITIALIZER(f) \
static void f(void) __attribute__((constructor)); \
static void f(void)
#elif defined(_MSC_VER)
#define INITIALIZER(f) \
static void __cdecl f(void); \
__declspec(allocate(".CRT$XCU")) void (__cdecl*f##_)(void) = f; \
static void __cdecl f(void)
#endif
INITIALIZER(initializer_1) { names[names_len++] = "new name"; }
INITIALIZER(initializer_2) { names[names_len++] = "new name 2"; }
If you are not 100% concerned with portability and you can guarantee GCC, you can do what you want with the "constructor" attribute in GCC. See: http://gcc.gnu.org/onlinedocs/gcc-4.1.1/gcc/Function-Attributes.html.
However, I agree with #Anders K when he says you should encapsulate that behaviour in functions.
I think in order to achieve what you want you would be better off to create a couple of wrapper functions to your names[] array. Then modules that access your 'global' names array would have to go through that interface.
This would allow you some better control and decoupling
You could then have the array in one module and then expose a those functions in a header but keep the array hidden.
I think initialization of a global variable works in C too.
int func1();
int someGlobalVariable = func1();
int func1()
{
/* Your initialization code can go here */
}
I hope I'm not mistaking about this working in C (been using only C++ for a very long time now).
Related
My C++ program needs to use an external C library.
Therefore, I'm using the
extern "C"
{
#include <library_header.h>
}
syntax for every module I need to use.
It worked fine until now.
A module is using the this name for some variables in one of its header file.
The C library itself is compiling fine because, from what I know, this has never been a keyword in C.
But despite my usage of the extern "C" syntax,
I'm getting errors from my C++ program when I include that header file.
If I rename every this in that C library header file with something like _this,
everything seems to work fine.
The question is:
Shouldn't the extern "C" syntax be enough for backward compatibility,
at least at syntax level, for an header file?
Is this an issue with the compiler?
Shouldn't the extern "C" syntax be enough for backward compatibility, at least at syntax level, for an header file? Is this an issue with the compiler?
No. Extern "C" is for linking - specifically the policy used for generated symbol names ("name mangling") and the calling convention (what assembly will be generated to call an API and stack parameter values) - not compilation.
The problem you have is not limited to the this keyword. In our current code base, we are porting some code to C++ and we have constructs like these:
struct Something {
char *value;
char class[20]; // <-- bad bad code!
};
This works fine in C code, but (like you) we are forced to rename to be able to compile as C++.
Strangely enough, many compilers don't forcibly disallow keyword redefinition through the preprocessor:
#include <iostream>
// temporary redefinition to compile code abusing the "this" keyword
#define cppThis this
#define this thisFunction
int this() {
return 1020;
}
int that() {
return this();
}
// put the C++ definition back so you can use it
#undef this
#define this cppThis
struct DumpThat {
int dump() {
std::cout << that();
}
DumpThat() {
this->dump();
}
};
int main ()
{
DumpThat dt;
}
So if you're up against a wall, that could let you compile a file written to C assumptions that you cannot change.
It will not--however--allow you to get a linker name of "this". There might be linkers that let you do some kind of remapping of names to help avoid collisions. A side-effect of that might be they allow you to say thisFunction -> this, and not have a problem with the right hand side of the mapping being a keyword.
In any case...the better answer if you can change it is...change it!
If extern "C" allowed you to use C++ keywords as symbols, the compiler would have to resolve them somehow outside of the extern "C" sections. For example:
extern "C" {
int * this; //global variable
typedef int class;
}
int MyClass::MyFunction() { return *this; } //what does this mean?
//MyClass could have a cast operator
class MyOtherClass; //forward declaration or a typedef'ed int?
Could you be more explicit about "using the this name for some variables in one of its header files"?
Is it really a variable or is it a parameter in a function prototype?
If it is the latter, you don't have a real problem because C (and C++) prototypes identify parameters by position (and type) and the names are optional. You could have a different version of the prototype, eg:
#ifdef __cplusplus
extern "C" {
void aFunc(int);
}
#else
void aFunc(int this);
#endif
Remember there is nothing magic about header files - they just provide code which is lexically included in at the point of #include - as if you copied and pasted them in.
So you can have your own copy of a library header which does tricks like the above, just becoming a maintenance issue to ensure you track what happens in the original header. If this was likely to become an issue, add a script as a build step which runs a diff against the original and ensures the only point of difference is your workaround code.
I came across a naming problem while working with the xlib library:
I'm using a struct which has a member called "class". I assume this library is mostly used in plain C programs. So there's no problem.
But I'm programming in C++ and here the name "class" is a keyword and cannot be used to denote variables. So, if I'm accessing the struct via
myvariable = mystruct->class;
I'm getting the error:
expected unqualified-id before ‘class’
Given that I cannot change the struct itself, how can I access this struct member despite the naming conflict?
Given that I cannot change the struct itself, how can I access this struct member despite the naming conflict?
Maybe you can rename it using a #define, something like
#define class xclass
#include "header.h"
#undef class
// ...
myvariable = mystruct->xclass;
class is a keyword in C++. You cannot use it as a variable.
If you want to still access it than you can code that part in C and then compile it with c compiler:
typedef struct foo {
bar class;
} foo;
bar *getClassPtr(foo *p) { return &(p->class); }
Include that part in your C++ code using,
extern "C" {
bar *getClassPtr(foo *);
}
bar &getClass(foo &s) { return *getClassPtr(&s); }
You might also want const versions.
You still can't include the struct definition in your C++ code, so you may have to wrap the other members of foo in the same way. Unless link-time optimization can inline getClassPtr, there's some overhead in the call, compared with accessing the struct member directly from C++. Normally this will be negligible, but it's worth knowing about.
You may want to find info about extern "C".
You say that you're using XLib. I can only find two places in my Xlib.h where class is used as a structure member: Visual and XWindowAttributes. In both cases, the offending member is wrapped like this:
#if defined(__cplusplus) || defined(c_plusplus)
int c_class;
#else
int class;
#endif
Similar hackery appears in XColormapEvent to take care of the new member.
So you should be fine unless your C++ compiler isn't defining any of the necessary macros; but that would also break the usual extern "C" { ... } wrappers as well so the problem is most likely elsewhere. If you're using a struct that isn't part of the standard XLib then you should apply the above hack by hand and have a stern discussion with the library's author (and if that's you then angrily talk to yourself for a bit and we'll pretend not to listen).
If you are having trouble with the XLib structs, then try using the C++ version of the member names:
myvariable = mystruct->c_class;
mynew = ev->c_new;
Class is a reserved keyword in C++ and cannot be used as a variable name. You will have to rename the variable.
In VC++, you can use Microsoft extension keyword: __identifier
int __identifier(float);
__identifier(float) = 10.4f;
MSDN says it is applicable for /clr (Managed C++) only, but that's not true. It existed even in VC6
As class is a keyword in C++, the compiler will complain if you use it
Maybe you could create a "wrapper" struct (in C) that allows to access your faulty structure, something like
typedef struct Wrapper_ {
faultyStruct * mystruct ;
faultyStructClass * cls ;
} Wrapper ;
Wrapper wrap(faultyStruct * s) {
Wrapper w = {s, &(s->class) } ;
}
Compile this file with your C compiler and use it in your C++ code through extern "C"
You can also use preprocessor to re-define class (but I'm not sure wether it is legal to #define C++ keywords
I have a class that only has static members.
I would like to register one of its member functions (VerifyClean in the code below) to be called at exit, using the "atexit" library function.
The C++ FQA says that i must specify extern "C" for the function i want to register this way, like in the following example.
class Example
{
public:
static void Initialize();
static void DoDirtyStuff {++dirtLevel;}
static void CleanUpStuff {--dirtLevel;}
private:
static void VerifyClean();
// DOESN'T COMPILE: extern "C" static void VerifyClean();
static int dirtLevel;
}
int Example::dirtLevel;
extern "C" void Example::VerifyClean() // DO I NEED extern "C" HERE?
{
assert(dirtLevel == 0);
}
void Example::Initialize()
{
dirtLevel = 0;
atexit(&VerifyClean);
}
Do i really have to use extern "C"?
Does the answer change if i replace "atexit" with a non-library function (implemented in plain C)?
If the function VerifyClean were public and i decided to call it directly from C++ code, would i get link errors or runtime crashes? I ask this because the declaration doesn't mention extern "C" at all, so regular C++ code might handle the function call incorrectly. This works OK on my MS Visual Studio 2005 system.
It is possible for a compiler to use different calling conventions for C and C++ code; however, in practice, this almost never occurs.
If you just want it to work and don't care about supporting obscure compilers, don't bother with extern "C". It's not necessary in any widely-used compiler.
If you want to be absolutely pedantic, or need to support a pedantic compiler, write a wrapper:
extern "C" static void ExampleVerifyClean()
{
Example::VerifyClean();
}
void Example::Initialize()
{
dirtLevel = 0;
atexit(&ExampleVerifyClean);
}
link errors.
C++ performs what is called name mangling, which generates a link-time function name with type information.
extern C turns that off into a simpler identifier.
edit:
If everything is being compiled by a C++ compiler, it won't be an issue. But if you have an object file compiled by a C compiler and one being compiled by a C++ compiler, you are going to have some issues.
I seem to recall DLLs requiring an extern "C" specification, but that memory is maybe 10 years old at this point
Okay.
I whipped up a test case with a function that had a signature
int foo(float, float)
And compiled it under 3 different gcc invocations -
gcc test_c.c -S
g++ test.cpp -S
These two invocations produced different identifiers in the assembly. The C++ had mangled the name in its usual type-modifying approach. (of course compilers may do this differently)
Then, I wrapped foo in Extern "C" and invoked G++ again...
g++ test.cpp -S
Which then removed the mangled C++ name, leaving a plain C unmangled name.
While there are other subtleties involved here, e.g., the order of arguments pushed onto the stack, I rest my case on this point, based on data.
Without extern "C", your function name will got mangled by compiler, so the function name might end up different from what you expect. You need to call the function using its mangled name (such as using GetProcAddress in windows) or you'll got linker error. Different compiler mangled it different way so it's best if you keep using extern keyword.
you might use this :
class yourname
{
public:
...
static void _cdecl AtExitCall ();
};
int main()
{
ataexit( yourname::AtExitCall );
}
It is a mistake to use extern "c" in this case for 2 reasons:
You use extern C, when you want to cross compile your program with a g++ (c++ compiler) for linking with gcc (C compiler). It tells g++ to turn off function name mangling. Clearly that is not your case here, or your whole file should be in extern "C"
When using extern "C" you should use c-like function names, like Example_VerifyClean.
Example::VerifyClean is not a valid c-function name and cannot be stored without mangling
I have a bunch of C code. I have no intention to convert them into C++ code.
Now, I would like to call some C++ code (I don't mind to modify the C++ code so that they are callable by C code).
class Utils {
public:
static void fun();
}
class Utils2 {
public:
static std::wstring fun();
}
If I tend to call them with the following syntax, they wont compiled (I am using VC++ 2008, with C code files with .c extension)
Utils::fun();
// Opps. How I can access std::wstring in C?
Utils2::fun();
Any suggestion?
// c_header.h
#if defined(__cplusplus)
extern "C" {
#endif
void Utils_func();
size_t Utils2_func(wchar_t* data, size_t size);
#if defined(__cplusplus)
}
#endif
//eof
// c_impl.cpp
// Beware, brain-compiled code ahead!
void Utils_func()
{
Utils::func();
}
size_t Utils2_func(wchar_t* data, size_t size)
{
std::wstring wstr = Utsls2::func();
if( wstr.size() >= size ) return wstr.size();
std::copy( wstr.begin(), wstr.end(), data );
data[wstr.size()] = 0;
return str.size();
}
//eof
What about a wrapper
extern "C" void Utilsfun(int i){Utils::fun(i);}
Update:
That is how you can call C++ functions from C, but accessing std::wstring from C is a different matter.
If you really wanted to manipulate C++ classes from C code then you could create an API where the classes are operated on with C++ functions, and passed back to C using void pointers. I've seen it done, but it's not ideal
extern "C"
{
void * ObjectCreate(){return (void *) new Object();}
void ObjectOperate(void *object, char *parameter){((Object*)object)->Operate(parameter);}
void ObjectDelete(void *object){delete ((Object*)object);}
}
You will have to be very careful about managing creating and deleting.
The most common solution is to write a C interface to your C++ functions. That is C++ code which are declared using extern "C" { ... }. These wrapper functions are free to call any C++ code they like, but since they're declared extern "C", they won't be subject to name mangling (you can't do namespaces or overloading here).
That ought to be linkable with your C file and you're good to go.
That is, the header file contains
#ifdef __cplusplus
extern "C" {
#endif
void wrapper1(void);
int wrapper2(int x);
char* wrapper3(int y);
#ifdef __cplusplus
}
#endif
The ifdefs are required to shield the C compiler from the extern "C".
And you implement those in your C++ source
void wrapper1(void) { Util::funcOne(); }
int wrapper2(int x) { return Util::funcTwo(x); }
char* wrapper3(int y) { return Util::funcThree(y); }
Create a wrapper function in your C++ code:
extern "C" void Wrapper() {
Utils2::fun();
}
and then in your C code:
extern void Wrapper();
int main() {
Wrapper();
return 0;
}
I think the only solution is to wrap them in C style global functions in the C++ code like:
extern "C" int Util2_Fun() { return Util2::Fun(); }
I suppose you could also declare global function pointers as externs using some nasty variation of:
extern int (*Utils2_Fun)()=(int *())(Util2::Fun);
And then call the function pointer directly from the C package using this pointer but there is little to recommend this approach.
You can make C++ callable from C by using the extern "C" construct.
If you do as ppl say here (using extern "C") beware that you only pass objects to the C function that would compile in C.
You won't have any practical use for c++ objects in your C code, so you'll probably want to create some sort of "C Binding" for your C++ code which consists of some number of ordinary functions that are callable from the C, and only return ordinary C data types. Your wrapper functions can then call all sorts of classes and objects, etc. But, they provide a simpler C-Style interface for the objects that you can use from C to bridge the gap. You can also use function pointers in some cases to give the C access to static methods, but it's usually easiest just to create the wrapper, IMHO.
You can either write global extern "C" wrapper functions or use function pointers to additionally make static class functions known to C. The C++ code can put these pointers in a global structure or pass them to C while calling a C function as a parameter. Also, you could establish a registry where the C code can request function pointers from C++ by supplying a string id. I've these all these varieties being used.
If you have control of all of the source, I wouldn't bother trying to keep part of it as C. It should be compilable as C++ (or easily changed to make it so). That doesn't mean you need to rewrite it as C++, just compile it as such. This way you can use whatever parts of C++ make sense. Over time, the C code make turn more C++ like, but this will happen slowly as the need arises.
Of course, if you need it to remain compilable in C for other reasons, this doesn't apply.
C is a subset of C++ ..
So u can not call c++ Class members and namespaces in C.
I've been reading questions on Stack Overflow for a few weeks now... this'll be my first question.
So recently I've looked into making C access/manipulate a C++ class. I understand that ideally one shouldn't compile components in C and C++ separately under normal circumstances, but this isn't an option at the moment.
I looked into 3 Tutorials regarding being able to port/use a C++ in C. They are:
"A Guide to C++ and C Interoperability" on DevX
"Mixing C and C++ Code in the Same Program" article on Sun's site.
"[32] How to mix C and C++" on Parashift
First, what I already know:
You must use extern "C" to avoid
C++ function name mangling.
You need callback prototypes that are C-compatible.
G++ must compile the C++ into .o files, GCC compiles the C-specific code into .o files, then link both after.
As a result, the project I have is made of 4 files:
foo.h, header that'll list all prototypes that C/C++ will see (classes invisible to C of course)
foo.cpp containing the Foo class, and a set of C-compatible callback functions to invoke the class and methods.
fooWrap.c a set of C-specific wrappers that reference the callback functions in foo.cpp.
main.c the test method.
Here's the code I typed up, then my questions:
FOO.H
// Header File foo.h
#ifndef FOO_H
#define FOO_H
//Content set inside this #ifdef will be unseen by C compilers
#ifdef __cplusplus
class Foo
{
public:
void setBar(int);
void printBar();
private:
int bar;
};
#endif
//end of C++-only visible components.
#ifdef __cplusplus
extern "C" {
#endif
//Stuff made to be seen by C compilers only. fooWrap.c has definitions.
#if defined(__STDC__) && !defined(__cplusplus)
typedef struct Foo Foo;
//C-wrappers for C++ callback functions.
Foo * c_NewFoo();
void c_SetFooBar( Foo *, int);
void c_PrintFooBar( Foo *);
#endif
//These are the functions C++ AND C can both use...
Foo * newFoo(); //allocates the memory for Foo class, pass address back.
void setFooBar( Foo * , int ); //set internal contents of Foo object.
void printFooBar ( Foo * ); //print internal contents of Foo object.
#ifdef __cplusplus
}
#endif
#endif /*FOO_H*/
TEST.C
#include "foo.h"
// test.c test file for wrappers that manipulate C++ objects.
main()
{
//looks very C++ like... this makes C-Programmers cringe doesn't it?
Foo * cfoo = c_NewFoo();
Foo * cppfoo = newFoo();
//using the C-specific wrappers.
c_SetFooBar(cfoo,31415);
c_PrintFooBar(cfoo);
//using the C/C++ callback functions to Foo objects.
setFooBar(cppfoo,9001);
printFooBar(cppfoo);
}
So I split the definitions up into the 4 files as I mentioned before... and it compiles fine. But here's what I don't quite get.
Why do the sun and parashift articles suggest to create C-Wrappers whose only code is to pass it's arguments onto C/C++ compatible functions who then call C++ specific code?
i.e.
//in Stuff.cpp
void CallCppStuff () { /* c++ stuff */ }
//in wrapStuff.c
wrapCppStuff() { CallCppStuff() }
As you can see from my test.c file... I'm able to call up either set of calls without a problem (as far as I can tell). Are the c_ wrappers needless overhead, or am I missing the whole point of them altogether? My only guess has something to do with pointer addressing schemes of C/C++... but I'm not sure.
Also, I imagine there are more issues beyond just this... but those 3 sites are all I could find specific to this problem. So if there are any other glaring oversights on my part, I'd appreciate their mentioning.
Thanks in advance for any help/advice,
CX
If you have a series of functions that are not object-orientated or in a namespace, there's no need to wrap them again. Your c_ series of functions are redundant.
Any C++ function that is extern C, has global (i.e., not namespace/static member) linkage, and only takes C-compat datatypes (normally we use opaque pointers like you have), then it doesn't need to be wrapped. That is the wrapping function. C++ uses member functions directly and doesn't need to use them, and they certainly don't need to be duped.