I'm playing with GCC IR and I want to check if the declaration was extern in C source:
extern int i;
I want to do that on GENERIC tree, to get something like this (by analogy to TREE_STATIC macro):
tree t;
if (TREE_EXTERN (t))
// do handling of extern
I've checked the GCC Internals documentation, but didn't find the needed function or macro.
I'm not an expert on GCC internals, but perhaps DECL_EXTERNAL is what you're looking for?
Related
Someone knows what does this error mean?
My piece of code is shown below:
// test.c
inline void fun() {
typedef struct {
int i;
} S;
}
GCC could compile without an error while clang (clang 12.0.0) claims an error:
root:~/test # clang -c test.c
test.c:2:19: error: unsupported: anonymous type given name for linkage purposes by typedef declaration after its linkage was computed; add a tag name here to establish linkage prior to definition
typedef struct {
^
S
test.c:4:7: note: type is given name 'S' for linkage purposes by this typedef declaration
} S;
^
1 error generated.
According to the error text from clang, it looks like I need to add a tag name for the anonymous typedef. After adding a tag name, it won’t show an error. However, this piece of code from a team work program in my department so I need a strong reason to modify it. Someone knows what’s this error mean?
UPDATE: In the comments below someone mentioned, The code could compile but fail to link with GCC. Actually that because the GCC optimization is not turned on. Use -O2 to compile and link will pass.
I mentioned this in a comment, but I think I might be able to expand it to a proper answer. The problem here is in how the inline keyword works in C. Quite frankly, I don't know what the C standards committee was smoking when they came up with this ridiculous concept, and it's probably best not to know. Don't ask why the rules are this way: I don't know.
There is an important difference between extern inline and static inline functions, as well as ones declared simply inline.
inline functions may be defined in a header and included in multiple compilation units. This is because they aren't considered "real" definitions. No symbol for them is emitted, thus there is no multiple-definition error. However, the compiler is not required to actually inline the function call. It may instead try to call it. Since no symbol exists, there will be an error at link time. Never use inline functions in C. They make no sense at all.
extern inline functions provide the definition for an inline function. If the above case happens, and the compiler tries to call the function, so long as some file includes an extern inline definition, there won't be an error because it emits a symbol. This making sense? No? Good.
static inline functions are the only one that make any sense whatsoever. Because they're static and therefore local, no symbol need exist. If the compiler decides to inline it, it does. If not, it calls the function. No problems. Declare your function static inline and it will compile.
But that wasn't your question. Why is clang complaining about the struct? Why doesn't gcc complain? The answer is "idunnoman". Best guess is that clang is taking the rules very seriously, in which case because there is no "real" definition for fun, there is also no real definition for your anonymous struct, and therefore can't be typedef'd.
But that would also be the case if it were a named struct. And why does the linker care whether the structure has a name? Once again, I can only guess it has to do with the fact that there can be numerous definitions for an inline function, and clang wants the structure to have a constant name between them. But different compilation units can have different structures with the same name, so that doesn't make sense either.
Ugh. I thought I had an answer for you but now I'm even more confused than when I started. I'll still post this but it probably ought to be downvoted. Oh well.
To get rid of a static code analysis warning (QA-C), I need to provide a function prototype for __builtin_expect().
I am using the WindRiver Diab compiler for PowerPC.
In the compiler manual I have found the following information:
__builtin_expect(long exp, long c): ... exp is also the return value.
So, my prototype is as follows:
long __builtin_expect(long exp, long c);
However, it does not compile, I am getting the following error:
error (dcc:1701): invalid types on prototype to intrinsic __builtin_expect - when the intrinsic is enabled, optional user prototype must match
It seems like my prototype is not correct. What is the correct prototype for __builtin_expect?
The error message states that the user prototype is optional. So it should be possible to define it, right?
You need to somehow define __builtin_expect to make your static analyzer happy, because it doesn't know what that function is. But you need to use #ifdef to disable that definition when you are compiling your program normally, because your compiler will not like it if you try to define compiler builtins yourself. The builtins come with the compiler so they are not supposed to be defined in your program.
Something like this would work:
#ifdef _HEY_I_AM_RUNNING_STATIC_ANALYZER
#define __builtin_expect(e,c) (e)
#endif
I don't know the details of how your static analyzer works, so I don't know what the right macro is to test in the #ifdef. You can read the documentation of your static analyzer to find out if it defines any preprocessor symbols by default, or if you can tell it what preprocessor symbols to define when you run it.
You should carefully read the documentation of Other Builtins in GCC.
As a first approximation, you might replace __builtin_expect by (invocation _builtin_expect_replacement of) the macro below:
#define _builtin_expect_replacement(Exp,C) (Exp)
For most static analyzers that should be enough
Don't expect most GCC builtins to be definable as functions.
I recently learned that there are parameter-type-lists which can be empty in C:
int print();
int main() {
print("hallo"); // << valid but highly unintuitive
}
int print() {
}
In this code someone might just have forgotten to write print(void) (maybe a C++ developer) but someone else provides a parameter. Compilation does not show any warnings or errors:
$ make test -Wstrict-prototypes -Wimplicit -Wimplicit-function-declaration -Wall
cc test.c -o test
I didn't find a compiler flag which warns about empty parameter-type-lists, only about implicit function declaration.
Is there something I can do which helps me finding all uses of parameter-type-lists in a given code base?
E.g.
letting a C++ compiler compile the C code as C++ and solve type issues (C++ does not allow arguments if the declaration does not list them)
let the compiler list all function declarations (don't know if possible) and searching manually for empty braces
greping for parameter-type-lists (too complex for me :))
disabling parameter-type-lists via compiler switch (didn't find any)
With gcc, using -Wstrict-prototypes will achieve what you expect:
-Wstrict-prototypes (C and Objective-C only)
Warn if a function is declared or defined without specifying the argument types. (An old-style function definition is permitted without a warning if preceded by a declaration that specifies the argument types.)
With your example, it gives:
hallo.c:1:5: warning: function declaration isn’t a prototype [-Wstrict-prototypes]
int print() {
^
However, you'll have to ensure that all non-strict function declarations in your existing code gets properly defined; in particular, functions without parameters should be declared with (void), like this:
int print(void);
Your example is not valid, neither in C nor in C++. Since your print() function does not accept any parameters -- which is well established from the function definition you provide (C2011, 6.7.6.3/14) -- it is non-conforming to call it with an argument, regardless of whether a prototype is visible at the point of the call (C2011, 6.5.2.2/6). If the call appears in a scope wherein neither the function definition nor any bona fide prototype is visible then the compiler might nevertheless accept the code, but that does not make it valid or guarantee that it will work.
Additionally, you seem to be using the wrong term, or possibly your idea is very wrong-headed. Parameter-type-lists are the modern way of declaring (and defining) functions, including function prototypes:
int my_func(int a, char *b);
// ^^^^^^^^^^^^^^----- parameter-type-list
You should not get rid of those, but I think you mean that you want to identify and fix K&R-style function definitions and also function declarations without parameter-type-lists. (The formal syntax's terms for the K&R style are "identifier list" and, if needed, an accompanying "declaration list".)
As for identifying the occurrences of K&R-style declarations automatically, that's a job for a C language parser, and the most common implementations of those are C compilers. Your compiler may have an option for just what you want. GCC, for example, has options -Wstrict-prototypes and -Wold-style-defintion, which, together, will signal both function declarations that are not prototypes and K&R-style function definitions. GCC has some other options that might be of interest to you too, such as -Wimplicit, -Wtraditional, and -Wc++-compat.
All you need to look for is () (with optional whitespace), followed by { (with optional whitespace, perhaps newline). And you can replace it with (void).
If you want an "industrial grade" solution you can use a compiler which emits something easier to parse, such as GCC-XML or Clang.
I'm currently working with an old C library (made in the early 90's) and the following function declaration made me confused :
#define bland_dll
typedef unsigned short int usint;
typedef unsigned char uchar;
int bland_dll Read_Chan (usint channel);
What is the bland_dll doing between the function's name and it's return type ?
Thanks for your lights!
Its a macro defining empty, so when preprocessed it turns out to be:
int Read_Chan (usint channel);
I suspect, its a holdover from the early days when declaring DLL linkage types, like pascal which has a special meaning to the linker, for example. Another example is __cdecl.
For completion of the idiosyncracies of compiler linkage mechanisms:
__stdcall
__fastcall
__cdecl
Each of them influenced how the linker managed the name decoration at compile time, and may have caused conniptions with linking to third party DLL's due to the differing link time switches.
Edit: Thanks unwind for the correction.
I want to import some C code but override its main() function. I can do this in Unix by prefacing the C code's main declaration with __attribute__((weak)), however, this won't compile in Windows, because neither Strawberry Perl's GCC nor MinGW's GCC recognize __attribute__((weak)).
Reading the docs online, __declspec seems to function similarly. Is there a __declspec equivalent to Unix GCC's __attribute__((weak)) macro?
This is a more specific version of an earlier question I posted.
There's another way with MSVC that I think would work if you care to use it.
/*
* pWeakValue MUST be an extern const variable, which will be aliased to
* pDefaultWeakValue if no real user definition is present, thanks to the
* alternatename directive.
*/
extern const char * pWeakValue;
extern const char * pDefaultWeakValue = NULL;
#pragma comment(linker, "/alternatename:_pWeakValue=_pDefaultWeakValue")
See this old SO answer for some other options.
There's also __declspec(selectany)