For the following code in C:
file.h
// declaration of extern function
extern void extFunc();
file.c
#include "file.h"
// declaration of static function
static void localFunc(uint32_t const input);
// definition of static function
void localFunc(uint32_t const input)
{
// do something
}
// definition of extern function
void extFunc()
{
// do something
}
When I compile the above code for ARM ISA target, I get compiler error saying
Error[Pe177]: function "localFunc" was declared but never referenced in C:\Users\admin\git\file.c
How to get rid of it ?
Error[Pe177]: function "localFunc" was declared but never referenced in C:\Users\admin\git\file.c
How to get rid of it ?
localFunc() is declared static. This means that the version of that function appearing in file.c is not accessible by name from other translation units. Your compiler is telling you that it is not accessed by name from the same translation unit either, and no pointer by which it could be called is exposed, so the function definitely is not called at all. It is dead code.
Normally this kind of issue warrants a warning instead of an error, but perhaps your compiler is especially strict, or you have enabled an option turns warnings into errors, so as to force you to resolve all diagnostics that otherwise would be just warnings. In any event, there are several possible solutions, but these are the most likely:
Delete localFunc() and its forward declaration from file.c, or comment them out, or suppress them via conditional compilation directives. This assumes that it is intentional that they are going unused.
Insert live code that calls localFunc(). This only makes sense if it was some kind of mistake that localFunc() was not being called within the translation unit already.
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.
I have a questions about using inline keyword in C code (C99).
I know C99 inline semantics are different than C++ or gnuC inline rules,
I have read
http://www.greenend.org.uk/rjk/tech/inline.html
and
extern inline
but, I just can't get this working.
I have a function definition as below in file1.c
inline myfunc(arguments)
{
}
And this function is called from another function in file2.c
In that file2.c I tried using
extern inline myfunc(arguments);
for this function before it is called from the other function
still I keep getting error - implicit declaration of myfunc
or undefined reference error if I remove the extern inline
Due to my code structure, cannot have the myfunc function definition in a header file nor can have it as static inline, as it has to be called from different compilation units.
What is that I am getting wrong? How to fix it.
After lot of reading about this, trial and error I have found answer to my problem above in a way I was looking for - Inline a C function definition present in a C source file, using C99 rules, without putting it in a header file.
I added the attribute always_inline keyword to the function definition and declaration as below and recompiled, it inlines the call to that function.
In file file1.c
__attribute__((always_inline)) void myfunc(arguments)
{
//... function definition
}
and in file1.h which has its declaration , I changed it to be as below
__attribute__((always_inline)) void myfunc(arguments);
I have this snippet of code:
int foo1(void); //line a
int foo2(void) {
return foo1();
}
int foo1(void) { //line b
return 99;
}
If I want to declare function foo1 to be static, should I put the keyword static in line a or line b? Is there any difference?
Also say I have the following code in ANOTHER file that uses foo1 in the above file:
static int foo1(void);
int main(void) {
return foo1();
}
The code still compiles and works as expected although I put static in the declaration line. But it gives a warning saying that 'foo1' used but never defined - if it's not defined, why does the code still work?
Edit:
Sorry I didn't make that clear, for the second question, foo1 in the first file where it's defined is not declared as static, but I declare it as static in the second file.
In the first case, you need to put static on both line a and b. Static functions in C has internal linkage meaning that they are only visible in the same file. So for declaration and definition, you need to put static so that compiler knows that the function has internal linkage. If you don't put static on line a, you will get some compilation errors.
In the second case, since foo1 is a static function, it must be defined in the same file as main. You only put a forward declaration without actual definition. Even though it compiles fine, the program will not link since foo1 is not defined.
The static keyword in this context specifies that foo1 not be exported, so that particular foo1 could only be defined in that same compilation module, hence the warning when it isn't. (Without the static the code would be correct, assuming you mean to link the foo1 from the other file.)
As for why it works regardless of this, my guess is that the compiler falls back on looking for the external function, which it finds from your other file, but I think a conforming compiler would be justified in giving an error here.
In C static for functions means internal linkage and use of the function only within the scope of the file.
Interesting that compilers behave differently:
Snippet 1:
GCC and clang requires putting static in declaration (line a), in definition (line b) it can b omitted then.
In MS VC you can put static in declaration or in definition only, this makes foo1() static.
Snippet 2 (static foo1 in main.c, non-static declaration in other file):
GCC compiles static declaration without definition. clang compiles but outs a warning. (Both link then.)
MS VS does not compile the second snippet at all, giving an error C2129.
So, put static in both declaration and definition for clarity, and define static functions in the files where they are declared. Put forward declarations if required before usage of the functions.
Overall, seems that clang has better diagnostics.
"...if it's not defined, why does the code still work?"
In C it is not required to declare prototype before function call. The definition is than found on the linkage step.
I have a static inline function defined in an H file, and at one point in a C file, I'm assigning a pointer to the function, something like this:
foo.h:
static inline void frobnicate(void) {
// frobs something.
}
foo.c
#include "foo.h"
void execute(void (*func)(void) ) {
func();
}
void blahBlahBlah(void) {
execute(frobnicate);
}
bar.c
#include "foo.h"
// ...
frobnicate();
So I think what will happen here is that the compiler will inline the call to frobnicate from bar.c, but in foo.c, it will actually have to create a function to implement frobnicate, so that it can have a working pointer to it.
Can anyone confirm if my understanding is accurate, and correct me otherwise?
inline is one of the misnomers of the C standard. Its main meaning is to be able to put the definition of a function in a header file without having to deal with "multiple definition" problems at link time.
The official way in C99 and C11 to do what you want to achieve is to have the inline definition in the header file, without the static. Since you also need the symbol to be emitted you need to tell the compiler in which compilation unit this should be. Such an instantiation can be done by have a declaration in that .c file where you omit the inline keyword.
Most naturally you could use the .c file where you actually need the symbol.
Yes, you are right. When you take the pointer to the function the compiler must create an "stand alone" version where the code can be called as a normal function.
The benefit of inlining a function is that the calling code need not to be created and any other optimization can be aplied to integrate both the caller function and the inlined function. But when you need to do a regular call to the function(as when you take the address to call it latter), those optimizations are not possible anymore.
I'm trying to compile the same C file on two different machines with different versions of cc.
gcc version 3.2.3 says warning: 'foo' was declared implicitly 'extern' and later 'static'
gcc version 4.1.2 says error: static declaration of 'foo' follows non-static declaration
Both have the same CFLAGS. I'd like to make gcc 4.1.2 behave like gcc 3.2.3, that is, find an option that would turn this error into a mere warning.
From what the error message complains about, it sounds like you should rather try to fix the source code. The compiler complains about difference in declaration, similar to for instance
void foo(int i);
...
void foo(double d) {
...
}
and this is not valid C code, hence the compiler complains.
Maybe your problem is that there is no prototype available when the function is used the first time and the compiler implicitly creates one that will not be static. If so the solution is to add a prototype somewhere before it is first used.
I have had this issue in a case where the static function was called before it was declared. Moving the function declaration to anywhere above the call solved my problem.
Try -Wno-traditional.
But better, add declarations for your static functions:
static void foo (void);
// ... somewhere in code
foo ();
static void foo ()
{
// do sth
}
While gcc 3.2.3 was more forgiving of the issue, gcc 4.1.2 is highlighting a potentially serious issue for the linking of your program later. Rather then trying to suppress the error you should make the forward declaration match the function declaration.
If you intended for the function to be globally available (as per the forward declaration) then don't subsequently declare it as static. Likewise if it's indented to be locally scoped then make the forward declaration static to match.
This error can be caused by an unclosed set of brackets.
int main {
doSomething {}
doSomething else {
}
Not so easy to spot, even in this 4 line example.
This error, in a 150 line main function, caused the bewildering error: "static declaration of ‘savePair’ follows non-static declaration". There was nothing wrong with my definition of function savePair, it was that unclosed bracket.
You have declared a function as nonstatic in some file and you have implemented as static in another file or somewhere in the same file can cause this problem also.
For example, the following code will produce this error.
void inlet_update_my_ratio(object_t *myobject);
//some where the implementation is like this
static void inlet_update_my_ratio(object_t *myobject) {
//code
}
If you remove the static from the implementation, the error will go away as below.
void inlet_update_my_ratio(object_t *myobject) {
//code
}
I had a similar issue , The function name i was using matched one of the inbuilt functions declared in one of the header files that i included in the program.Reading through the compiler error message will tell you the exact header file and function name.Changing the function name solved this issue for me