extern followed by string literal - c

I am trying to parse the syntax of a C file using pycparser. I send the C file through a preprocessor and then send the output of the preprocessor to be parsed by pycparser. The following code is in one of the C files ...
extern "asm"
{
extern void ASM_Function(void);
}
pycparser throws and exception telling me this is not valid C syntax. Looking at the C BNF the keyword extern does not allow a string literal to precede it. I am correct in reading the BNF? Was this extern functionality added in a later version of C or is this syntax compiler specific?

It looks like a compiler extension. Do you know what compiler the code was originally written for?
Most compilers support declaring a C calling convention by wrapping the function declaration with an:
#ifdef __cplusplus
extern "C" {
#endif
// functions that use C calling convention.
// are declared here.
#ifdef __cplusplus
} /* extern "C" */
#endif
The code appears to be declaring an externally defined assembly function called ASM_Function. You may be able to rewrite this if you know what is the calling convention the assembly function is expecting.
extern "C" is a C++ construct to declare functions that will not use name mangling and will use the cdecl calling convention.
EDIT: Corrected my post.

Related

How can I insert C code into C++/CLI code?

I have some files written in C that I want to insert into my .NET C++/CLI code.
This C code is huge and has not been written by me, so it would be a hard task to me 'translating' all the code.
How can I insert this code and call the functions I need without any compatibility problems?
I used to think that, if C++/CLI is definitely C++ and C is compatible with C++, there is no problem to insert C code into C++/CLI code. But I've read about something called extern "C", which made me change my mind.
How can I insert the code into my project, preferably in another file?
Thank you in advance.
C++ can run C code without modifications. The only difference is the way the names of functions and variables are encoded. The process is called name mangling.
Just enclose your C code (headers and source) in a extern "C" block:
extern "C" {
... (C code)
}
All C code must be written in such a block. This tells C++ compiler how to treat function and variable names. Read more about extern "C" here.
What Mario is writing is correct. I am just modifying his example below. Just add all the header file declaration like below and compile you code to use all the function declared in c into your C++ application. Also include c libraries into your make file as well.
#ifdef __cplusplus
extern "C" {
#endif
//declare your header file here
#include "your c header file"
void foo(int i);//your c function
#ifdef __cplusplus
}
#endif

Is calling atoi without stdlib undefined behaviour?

Is calling atoi without including stdlib.h undefined behaviour?
I can't find where I have included stdlib.h in my project, even though I have used atoi.
The thing is actually atoi has been working fine - it has been parsing integers correctly every time the software has been used.
It is some embedded device.
So is there case this can be well defined?
btw. In this line:
#ifdef __cplusplus
#if __cplusplus
extern "C"{
#endif
#endif /* __cplusplus */
#include "sdkGlob.h"
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */
that header includes stdlib.h but I can't understand in which case it is included. And I am not sure if this cplusplus is defined anywhere. This is a c project anyway.
Prior to C99 it was acceptable to use functions that hadn't previously been declared. The compiler might generate a warning but there would be no error until the linker either didn't find the function or found a function of the same name with a signature other than the one that the compiler had guessed. Luckily for you, the compiler always guesses a return type of int.
In C99 it became necessary for function declarations to be visible but not all compilers strictly enforce the rule.
As per Random832's comment, it's also quite possible that sdkGlob simply includes stdlib for itself.
As to your other question: sdkGlob is always included but if run through a C++ compiler rather than a C compiler you also get the extern "C"{ .. } wrapping. That tells the C++ compiler not to mangle the names so that you can link against a version of that module that was built using an ordinary C compiler. It's the normal way to provide plain C libraries in a way that allows them to be used by both C and C++ code.
The short answer
Two possibilities:
It's probable that sdkGlob.h include stdlib.h or define its own version of atoi.
Some compilers, like GCC, resolve missing #include and even hide the errors or warnings. Run gcc -Wall and check if warnings appears.
About ifndef
The #ifdef __cplusplus sections are used by C++ compilers. Here, you're saying '*if and if only the code is being compiled by a C++ compiler, do ... *'.
The C-only version of your code:
#include "sdkGlob.h"
The C++-only version of your code:
extern "C"{
#include "sdkGlob.h"
}

How to detect that extern "C" is in effect

I am trying to find all places where #include is placed inside extern C block. Is is possible to check this using preprocessor? I would like to do add something like this to my header files:
#ifdef EXTERN_C_IS_IN_EFFECT
#error File included from extern "C" block!
#endif
I am also looking for other ways to fail compilation in such case, e.g. use some special attribute. I am using gcc 4.4.7.
I defined following macro and then use it in every header which needs protection against inclusion in extern C block:
#define ASSERT_NO_EXTERN_C void assert_no_extern_c(int); void assert_no_extern_c(double);
Maybe you can define 2 function prototypes with same name and different parameters. You will get warnings in case of extern "C" block. And it is allowed in C++.
That's not possible because the preprocessor runs before any syntactical analysis is done; that is, the preprocessor doesn't even know what extern "C" is and it's action cannot depend on the presence of such a directive either.
However, linkage specifications do nest, so instead of making sure the includer did not specify extern "C", you could place your header within an extern "C++" specification to make sure that it uses C++ linkage.

Does it prohibited calling classic C function from Objective-C++ class method body?

I have experienced some strange behavior of Objective-C++.
I have an Objective-C++ class, and it calls a classic C function in a method body.
But linker cannot find the C function.
I described the problem here:
Xcode print symbol not found for my C function which used in Objective-C method body
I solved the problem by changing Objective-C++ class to Objective-C class, but the question is still remained. Does it prohibited calling C function in Objective-C++ class?
You need to make sure that the C functions are declared
extern "C"
in the appropriate .h file.
The common way of doing this is:
//
// foo.h
//
#ifndef __FOO_H__
#define __FOO_H__
#ifdef __cplusplus
extern "C" {
#endif
// ... your interface here - normal C function declarations etc ...
#ifdef __cplusplus
}
#endif
#endif

C function seemingly not defined anywhere!

I'm looking at the vim source code, specifically the file normal.c, and I see this function nv_operator being used, but it's not defined anywhere (I grepped the entire src directory)
It's only declared as:
static void nv_operator __ARGS((cmdarg_T *cap));
I've looked up the definition of __ARGS but it's just ... nothing (pretty much)
in vim.h:
#define __ARGS(x) x
So what could be going on? Is this some kind of C technique to create a dummy function or something?
There is a definition present here:
/*
* Handle an operator command.
* The actual work is done by do_pending_operator().
*/
static void
nv_operator(cap)
cmdarg_T *cap;
....
That style of definition is using an identifier list for its parameters. The style is deprecated (obsolescent) but can still be used in C. The identifiers are named in the parameter list, and their type are named in declarations that immediately follow the function declarator but precede the functions body.
The __ARGS macro is there to handle compilers that don't know about prototypes for functions (the other form to declare parameters - with type and name combined directly in the function parameter list). It would then just emit no parameters at all in declarations, i think.
Update: See this code in vim.h:
#if defined(MACOS) && (defined(__MRC__) || defined(__SC__))
/* Apple's Compilers support prototypes */
# define __ARGS(x) x
#endif
#ifndef __ARGS
# if defined(__STDC__) || defined(__GNUC__) || defined(WIN3264)
# define __ARGS(x) x
# else
# define __ARGS(x) ()
# endif
#endif
It's simply a forward declaration, so that the function is known to the C compiler (and can be used (called from other functions)) before it's actually defined (in line 8247). The actual formatting of the definition (which includes newlines) makes it hard to grep for it's existence.
Don't get distracted by the __ARGS macro. It's only a compatibility macro for the different function declaration syntaxes of K&R C vs. ANSI C.
In ANSI C a function declaration must look like this:
int getopt(int, char * const *, const char *);
In the (older) Kernighan and Ritchie C http://en.wikipedia.org/wiki/C_(programming_language)#K.26R_C
int getopt();
Its hard to find because of how it is defined:
nv_operator(cap)
appears on a line by itself.
I am not too sure what is going on, but here are some hints to help you in your search:
First of all, the __ARGS macro seems to be there because there may be versions of C where you shouldn't include the args in the declaration of the functions (Notice that the macro is defined differently depending on other preprocessor symbols... the comments say it).
Secondly, searching for the function nv_operator may not be good enough. The function might be generated by macros and such, so you can't search for an explicit definition.... for example, maybe the "nv" prefix is added by the preprocessor.
Hope this helps.

Resources