How to address warning about function in header file? - c

This is concerning one of the functions in my header file(battleship.h).
Here is the code for my function prototype
int gameOver();.
Inside my main C file, here is my code for using that function and including that header file
#include "battleship.c"
int main ()
{
while(!gameover)
{
......
}
}
When I tried compiling the main c file(repo.c) into object code with this command
gcc -c repo.c
I got the warning "the address of 'gameOver', will always evaluate as 'true'. Is there any way I can address this warning?

You probably intended to call the function instead of simply taking its address:
while(!gameOver())
{
...
Note the parentheses.

Related

LLVM cannot see static function

I am trying to instrument the linux kernel code to insert a function call in every function right after a BitCast instruction.
So I modify the C code to #include <linux/my_header.h> where I have my printer function.
The header looks something like this.
#ifndef __header_ID
#define __header_ID
static inline void print_typecast(...){
printk(...);
}
#endif
Then I use Xclang to load my FunctionPass, which looks something like this.
// M is of type llvm::Module*
Function* f = M->getFunction("print_typecast");
if (f == nullptr) {
errs() << "Function not found in the module\n";
}
else {
// insert function in the code
}
However, my pass never finds the function in the module. When I remove the static it will find the function but then the linker in the final compilation step will complain of duplicate definition.
Anyone knows how to make LLVM "see" static imported/included functions?
Edit: I have also gone to the extreme where I have the same function directly written in every c file of the kernel code (the ones that #include <linux/kernel.h>)
static means that all calls to this function will be visible to this compiller now, and by implication that if the compiler sees no such calls, then it can skip compiling any output for the function, because you as programmer have promised that noone will want it.

changing extern function pointer to extern pointer using preprocessor

I am using library that I shouldn't change it files, that including my h file.
the code of the library looks somthing like like:
#include "my_file"
extern void (*some_func)();
void foo()
{
(some_func)();
}
my problem is that I want that some_func will be extern function and not extern pointer to function (I am implementing and linking some_func). and that how main will call it.
that way I will save little run time and code space, and no one in mistake will change this global.
is it possible?
I thought about adding in my_file.h somthing as
#define *some_func some_func
but it won't compile because asterisk is not allowed in #define.
EDIT
The file is not compiled already, so changes at my_file.h will effect the compilation.
First of all, you say that you can't change the source of the library. Well, this is bad, and some "betrayal" is necessary.
My approach is to let the declaration of the pointer some_func as is, a non-constant writable variable, but to implement it as constant non-writable variable, which will be initialized once for all with the wanted address.
Here comes the minimal, reproducible example.
The library is implemented as you show us:
// lib.c
#include "my_file"
extern void (*some_func)();
void foo()
{
(some_func)();
}
Since you have this include file in the library's source, I provide one. But it is empty.
// my_file
I use a header file that declares the public API of the library. This file still has the writable declaration of the pointer, so that offenders believe they can change it.
// lib.h
extern void (*some_func)();
void foo();
I separated an offending module to try the impossible. It has a header file and an implementation file. In the source the erroneous assignment is marked, already revealing what will happen.
// offender.h
void offend(void);
// offender.c
#include <stdio.h>
#include "lib.h"
#include "offender.h"
static void other_func()
{
puts("other_func");
}
void offend(void)
{
some_func = other_func; // the assignment gives a run-time error
}
The test program consists of this little source. To avoid compiler errors, the declaration has to be attributed as const. Here, where we are including the declarating header file, we can use some preprocessor magic.
// main.c
#include <stdio.h>
#define some_func const some_func
#include "lib.h"
#undef some_func
#include "offender.h"
static void my_func()
{
puts("my_func");
}
void (* const some_func)() = my_func;
int main(void)
{
foo();
offend();
foo();
return 0;
}
The trick is, that the compiler places the pointer variable in the read-only section of the executable. The const attribute is just used by the compiler and is not stored in the intermediate object files, and the linker happily resolves all references. Any write access to the variable will generate a runtime error.
Now all of this is compiled in an executable, I used GCC on Windows. I did not bother to create a separated library, because it doesn't make a difference for the effect.
gcc -Wall -Wextra -g main.c offender.c lib.c -o test.exe
If I run the executable in "cmd", it just prints "my_func". Apparently the second call of foo() is never executed. The ERRORLEVEL is -1073741819, which is 0xC0000005. Looking up this code gives the meaning "STATUS_ACCESS_VIOLATION", on other systems known as "segmentation fault".
Because I deliberately compiled with the debugging flag -g, I can use the debugger to examine more deeply.
d:\tmp\StackOverflow\103> gdb -q test.exe
Reading symbols from test.exe...done.
(gdb) r
Starting program: d:\tmp\StackOverflow\103\test.exe
[New Thread 12696.0x1f00]
[New Thread 12696.0x15d8]
my_func
Thread 1 received signal SIGSEGV, Segmentation fault.
0x00000000004015c9 in offend () at offender.c:16
16 some_func = other_func;
Alright, as I intended, the assignment is blocked. However, the reaction of the system is quite harsh.
Unfortunately we cannot get a compile-time or link-time error. This is because of the design of the library, which is fixed, as you say.
You could look at the ifunc attribute if you are using GCC or related. It should patch a small trampoline at load time. So when calling the function, the trampoline is called with a known static address and then inside the trampoline there is a jump instruction that was patched with the real address. So when running, all jump locations are directly in the code, which should be efficient with the instruction cache. Note that it might even be more efficient than this, but at most as bad as calling the function pointer. Here is how you would implement it:
extern void (*some_func)(void); // defined in the header you do not have control about
void some_func_resolved(void) __attribute__((ifunc("resolve_some_func")));
static void (*resolve_some_func(void)) (void)
{
return some_func;
}
// call some_func_resolved instead now

Redefining main to another name

In C90, can I redefine main and give it another name, and possibly add extra parameters using #define?
Have this in a header file for example:
#include <stdio.h>
#include <stdlib.h>
#define main( void ) new_main( void )
int new_main( void );
The header doesn't show any errors when compiling.
When I try compiling it with the main C file, however, I keep getting an error
In function '_start': Undefined reference to 'main'
No, you cannot do that, because it would be against language and OS standards. The name main and its arguments argc, argv and environ constitute a part of system loader calling conventions.
A bit simplifying explanation (no ABI level, just API level) ensues. When your program has been loaded into memory and is about to start, the loader needs to know which function to call as an entrypoint, and how to pass its environment to it. If it was be possible to change the name of main and/or its parameter list, it would have been needed to communicate details of new calling interface back to the loader. And there is no convenient way to do it (apart from writing your own executable loader).
In function '_start': Undefined reference to 'main'
Here you can see an implementation detail of Linux/POISX ELF loader interface. The compiler adds function _start to your program behind the scenes, which is an actual program entrypoint. _start is tasked to do extra initialization steps common to most programs that use LibC. It is _start that later calls your main. Theoretically, you could write a program that has its own function called _start and no main and it would be fine. It is not trivial as you will have to make sure that the default _start code is no longer being attached to your program (no double definitions), but it is doable. And no, you cannot choose other name than _start for the same reasons.
The presence of #define main new_main within a compilation unit will not affect the name of the function the implementation will call on program startup. The implementation is going to call a function called main regardless of any macros you define.
If you are going to use a #define like that to prevent the primary declaration of main() from producing a function by that name, you'll need to include a definition of main() somewhere else; that alternate version could then invoke the original. For example, if the original definition didn't use its arguments, and if the program exits only by returning from main() [as opposed to using exit()] you might put #define main new_main within a header file used by the primary definition of main, and then in another file do something like:
#include <stdio.h>
#include <conio.h> // For getch() function.
int main(void)
{
int result = main();
printf("\nExit code was %d. Strike any key.\n", result);
getch();
return result;
}
In most cases, it would be better to add any such code within the ordinary "main" function, but this approach can be useful in cases where the file containing main is produced by code generation tools on every build, or for some other reason cannot be modified to include such code.
No you cannot (as Grigory said).
You can however, immediate call your proxy main,
int
your_new_main(int argc, char* argv[], char* envp[]) {
... //your stuff goes here
}
//just place this in an include file, and only include in main...
int
main( int argc, char* argv[], char* envp[])
{
int result = your_new_main(argc, argv);
return result;
}
As far as whether envp is supported everywhere?
Is char *envp[] as a third argument to main() portable
Assuming you're using gcc passing -nostdlib to your program, and then set a new entry, by passing this to gcc which passing it to the linker, -Wl,-enew_main. Doing this won't give you access to any of the nice features that the C runtime does before calling your main, and you'd have to do it yourself.
You can look at resources about what happens before main is called.
What Happens Before main

implicit declaration of function ‘mygets’ [-Wimplicit-function-declaration] mygets(str1);

[I've been looking at other questions and none of the solutions have worked so I'll ask my own question.
I'm working on a Ubuntu Kylin16.04(China version) and having trouble compiling my code, here are my gets function, the error received by the compiler]1
Implicit declaration of function means that you don't have function reference somewhere in header file normally.
Or maybe you have it, but the file where your function is called does not see this.
//Declaration, must always be before first function call
void myfunc(void);
//Function usage somewhere in the code
int main(void) {
//Call it here, compiler see the reference and knows what type
//of func it is and what parameters should be used to func
myfunc();
}
//Definition, write function content here
//This part will be compiled in separate way, linked will put everything together
void myfunc(void) {
//Write function content here
}

Using a file-static function as a callback from a different translation unit

Consider the following code:
a.c
#include <stdio.h>
#include "b.h"
static int a = 41;
static void test(void){
a++;
printf("a: %d\n", a);
}
int main(void){
set_callback(test);
call();
return 0;
}
b.c
static void (*callback)(void);
void set_callback(void (*func)(void)){
callback = func;
}
void call(void){
if (callback){
callback();
}
}
b.h
void set_callback(void (*func)(void));
void call(void);
This compiles without warnings with -Wall and prints out a: 42 as expected.
Now, this might not be the best practice, since the writer of a.c probably doesn't expect test() to be called from another file and the variable a modified, but is this legal C code? Will it work portably on different platforms and compilers?
Yes, this is perfectly fine code and even good code. There is no need for your test callback to be global.
The compiler is responsible to ensure that the function isn't called outside the translation unit, before doing any optimizations that would affect calling it from outside.
If it sees that a pointer to the function is passed to an external function, it has to refrain from doing incompatible optimizations to the function.
Thus, the only effect is that the object file won't export a test symbol (This is termed Internal Linkage).
You wrote,
Now, this might not be the best practice, since the writer of a.c probably doesn't expect test() to be called from another file and the variable a modified, but is this legal C code?
If the writer did not want his test() function to be called from another file, he should not have passed a pointer to it to an outside module!
When the writer called set_callback(test); he knew he was passing his static method to an outside module, and giving that outside module permission to call it.
The point is that the author is in charge of the test method and where it goes. He's not prevented from doing anything, but he can control where his data goes; and he chose to pass it to an outsider.

Resources