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.
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.
I am developing a program in C and I need to have one .h file and two .c files that share the same name on the methods but have different implementations. So basically what I am trying to do is:
header.h --->
void f();
void d();
source1.c --->
#include "header.h"
void f(){
print("Hello");
}
void f(){
print("World");
}
source2.c --->
#include "header.h"
void f(){
print("My name");
}
void f(){
print("is Danni");
}
but I have an error of multiple declarations :(
So I was wondering if there is any kind of trick about how to do this, maybe using macros or somenthing like that.
Thanks...
Well, there are two solutions ..
The first solution (not recommended)
It is based entirely on the compilation process. You simply compile the source.c file with the main function with the source you want to use. This should work without errors simply because the compiler is not aware of the other file. This is not recommended because it provides the same functionality (at some extent), use the same header file but are seperated source files. You might risk losing one of them. Also, you have to be aware of that whenever you're compiling a program that uses that header.
The second solution (recommended)
It is based on the preprocessing step, which is much more safer than the compilation command because it works the same with any compiler options or commands.
You have to use Macro Conditionals because they're processed before compilation. The behaviour of macro conditionals is almost entirely based on variable existence or comparison.
You can use something like that:
#ifndef _HEADER_H
#define _HEADER_H
void f();
void d();
#ifndef _HEADER_H_2 /* Where this is the default behavior if nothing the macro wasn't defined */
# include "source1.c"
#else
# include "source2.c"
#endif
#endif /* _HEADER_H */
I have some legacy code, which uses the macro definition as
#ifdef def_STATIC
#define STATIC static
#else
#define STATIC
#else
#endif
I understand using STATIC will help limiting the scope of variables depending on def_STATIC
but in what cases is this practice used ?
How is it helpful ?
I have never faced such macro myself, but according to this: "XFS removal of #define STATIC static" source it was used to disable static functions because GDB couldn't properly debug static inline functions. That's why this macro was used to temporarily make them non-static.
Correct me if I'm wrong, I've just googled it :)
An interesting question really)
Say I have this small function in a source file
static void foo() {}
and I build an optimized version of my binary yet I don't want this function inlined (for optimization purposes). is there a macro I can add in a source code to prevent the inlining?
You want the gcc-specific noinline attribute.
This function attribute prevents a
function from being considered for
inlining. If the function does not
have side-effects, there are
optimizations other than inlining that
causes function calls to be optimized
away, although the function call is
live. To keep such calls from being
optimized away, put
asm ("");
Use it like this:
void __attribute__ ((noinline)) foo()
{
...
}
GCC has a switch called
-fno-inline-small-functions
So use that when invoking gcc. But the side effect is that all other small functions are also non-inlined.
I know the question is about GCC, but I thought it might be useful to
have some information about compilers other compilers as well.
GCC's
noinline
function attribute is pretty popular with other compilers as well. It
is supported by at least:
Clang (check with __has_attribute(noinline))
Intel C/C++ Compiler (their documentation is terrible, but I'm
certain it works on 16.0+)
Oracle Solaris Studio back to at least 12.2
ARM C/C++ Compiler back to at least 4.1
IBM XL C/C++ back to at least 10.1
TI 8.0+ (or 7.3+ with --gcc, which will define __TI_GNU_ATTRIBUTE_SUPPORT__)
Additionally, MSVC supports
__declspec(noinline)
back to Visual Studio 7.1. Intel probably supports it too (they try to
be compatible with both GCC and MSVC), but I haven't bothered to
verify that. The syntax is basically the same:
__declspec(noinline)
static void foo(void) { }
PGI 10.2+ (and probably older) supports a noinline pragma which
applies to the next function:
#pragma noinline
static void foo(void) { }
TI 6.0+ supports a
FUNC_CANNOT_INLINE
pragma which (annoyingly) works differently in C and C++. In C++, it's similar to PGI's:
#pragma FUNC_CANNOT_INLINE;
static void foo(void) { }
In C, however, the function name is required:
#pragma FUNC_CANNOT_INLINE(foo);
static void foo(void) { }
Cray 6.4+ (and possibly earlier) takes a similar approach, requiring
the function name:
#pragma _CRI inline_never foo
static void foo(void) { }
Oracle Developer Studio also supports a pragma which takes the
function name, going back to at least Forte Developer
6,
but note that it needs to come after the declaration, even in recent
versions:
static void foo(void);
#pragma no_inline(foo)
Depending on how dedicated you are, you could create a macro that
would work everywhere, but you would need to have the function name as
well as the declaration as arguments.
If, OTOH, you're okay with something that just works for most people,
you can get away with something which is a little more aesthetically
pleasing and doesn't require repeating yourself. That's the approach
I've taken for Hedley, where the
current version of
HEDLEY_NEVER_INLINE
looks like:
#if \
HEDLEY_GNUC_HAS_ATTRIBUTE(noinline,4,0,0) || \
HEDLEY_INTEL_VERSION_CHECK(16,0,0) || \
HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
HEDLEY_TI_VERSION_CHECK(8,0,0) || \
(HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__))
# define HEDLEY_NEVER_INLINE __attribute__((__noinline__))
#elif HEDLEY_MSVC_VERSION_CHECK(13,10,0)
# define HEDLEY_NEVER_INLINE __declspec(noinline)
#elif HEDLEY_PGI_VERSION_CHECK(10,2,0)
# define HEDLEY_NEVER_INLINE _Pragma("noinline")
#elif HEDLEY_TI_VERSION_CHECK(6,0,0)
# define HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;")
#else
# define HEDLEY_NEVER_INLINE HEDLEY_INLINE
#endif
If you don't want to use Hedley (it's a single public domain / CC0
header) you can convert the version checking macros without too much
effort, but more than I'm willing to put in ☺.
A portable way to do this is to call the function through a pointer:
void (*foo_ptr)() = foo;
foo_ptr();
Though this produces different instructions to branch, which may not be your goal. Which brings up a good point: what is your goal here?
In case you get a compiler error for __attribute__((noinline)), you can just try:
noinline int func(int arg)
{
....
}
static __attribute__ ((noinline)) void foo()
{
}
This is what worked for me.
Use the noinline attribute:
int func(int arg) __attribute__((noinline))
{
}
You should probably use it both when you declare the function for external use and when you write the function.
I work with gcc 7.2. I specifically needed a function to be non-inlined, because it had to be instantiated in a library. I tried the __attribute__((noinline)) answer, as well as the asm("") answer. Neither one solved the problem.
Finally, I figured that defining a static variable inside the function will force the compiler to allocate space for it in the static variable block, and to issue an initialization for it when the function is first called.
This is sort of a dirty trick, but it works.
I couldn't get __attribute__((noinline)) to work, but this works on clang and GCC.
The Linux kernel defines noinline.
include/linux/compiler_attributes.h:#define noinline __attribute__((__noinline__))
#include <linux/kernel.h>
static noinline void foo(void);