Error: invalid value 'precompiled-header' in '-x precompiled-header' - c

I had to create a file.h which I put into my includes/ directory.
I meet a problem when comes time to GCC:
The error I get is:
error: invalid value 'precompiled-header' in '-x precompiled-header'
And I have absolutely no idea about what causes this!
Here is my main, ask me if you need to see more of my code.
I compile with this line of command : gcc -Wall -Wextra -Werror main.c includes/* srcs/* do-op.c
#include "includes/ft.h"
int main(int ac, char **av)
{
int a;
int b;
char c;
(void)ac;
a = ft_atoi(av[1]);
b = ft_atoi(av[3]);
c = av[2][0];
ft_putnbr(ft_do_op(a, b, c));
}

You state that your command to build is:
gcc -Wall -Wextra -Werror main.c includes/* srcs/* do-op.c
That means you're compiling the header files, which you normally should not do. What you should do is tell the compiler where it can find the header files, which is done with the -I (upper case i) option:
gcc -Wall -Wextra -Werror -Iincludes main.c srcs/* do-op.c

Related

Different behavior between clang and gcc-10 when linking to static library containing global variables

I have a statically linked library, containing a global variable barvar. I can compile the library with no problems with either gcc-10 or clang (this is on macOS Catalina). Interestingly, the behavior differs between the two when I try to link it into a program that uses the library. Here's the code:
In globvars.h, int barvar is declared:
#ifndef H_GLOBVARS_H
#define H_GLOBVARS_H
extern int barvar;
#endif
In globvars.c, int barvar is defined:
#include "globvars.h"
int barvar;
In foo.c, the function foo sets and prints barvar:
#include <stdio.h>
#include "globvars.h"
void foo()
{
barvar = 10;
printf("barvar is: %d\n", barvar);
return;
}
Here's test.c, the program that uses the library:
void foo();
int main(int argc, char **argv)
{
foo();
return 0;
}
When I compile and link with gcc-10, no problems:
gcc-10 -c foo.c -o foo.o
gcc-10 -c globvars.c -o globvars.o
gcc-10 -c test.c -o test.o
gcc-ar-10 rcs liblinktest.a foo.o globvars.o
gcc -o testlinkrun test2.o -L. -llinktest
When I compile and link with clang, I get an undefined symbol error at the last step:
cc -c foo.c -o foo.o
cc -c globvars.c -o globvars.o
cc -c test.c -o test.o
ar rcs liblinktest.a foo.o globvars.o
cc -o testlinkrun test2.o -L. -llinktest
with error:
Undefined symbols for architecture x86_64:
"_barvar", referenced from:
_foo in liblinktest.a(foo.o)
Any ideas? Interestingly, it appears the only step that has to be done with gcc-10 is compiling globvars.c. I can use clang and the clang linker for all other steps, and everything is fine. Is it possible that clang is optimizing away all the variables in globvars.c? How can I prevent this?
As #EricPostpischil observed in this comment, the issue is that clang defaults to treating barvar as a common symbol. Either changing int barvar; to int barvar = 0;, or compiling with -fno-common, fix the issue.
Beginning with gcc-10, gcc's default behavior is -fno-common instead of -fcommon.

Create a static libary and link against it

Hello beautiful people,
i'm trying to create a static libary and to compile against it.
I've allready created a small static libary and a header for it.
Header (math.h):
int add (int a, int b);
int sub (int a, int b);
add.c:
int add (int a, int b) { return a + b; }
sub.c:
int sub (int a, int b) { return a - b; }
I've created my static libary with the following commands:
gcc -c add.c
gcc -c sub.c
ar rcs libmymath.a add.o sub.o
Now my main.c
#include <stdio.h>
#include "math.h"
int main( int argc, char **argv ) {
printf("Result : %d\n", add(5,7) );
return 0;
}
I can compile it with the following command:
gcc main.c libmymath.a -o main
But if i compile it the following way, it fails.
gcc main.c -lmymath -L. -o main
It fails with the following error:
/usr/bin/ld: cannot find -lmymath collect2:
error: ld returned 1 exit status
even a change to
gcc main.c -llibmymath -L. -o main
fails and even if i include the header mymath.h to gcc
Can you help me ?
gcc understood -lmymath by libmath.so or libmath.a already. So when you add lib word in -llibmymath. This case the gcc understood your library name being liblibmymath.a. So, please replace this command
gcc main.c -llibmymath -L. -o main
by
gcc main.c -o main -L. -lmymath
It should work.

Use of extern variable in c

I have made two files in c i.e. file1.c file2.c. In file1.c I wrote
#include< stdio.h >
int s=10;
void main()
{
printf("This is file 1");
}
In file2.c
include < stdio.h >
extern int s;
void main() {
printf("%d",s);
}
When I compiled file2.c in ubuntu terminal I got undefined referenced to s error.
How can I resolve this error?
In the second case,
extern int s;
tells the compiler that "somewhere there" exists a variable s which has type int, but it actually does not "define" the variable. So, the linker has no clue where to find the variable, it cannot find the variable and throws the error.
You need to have a definition of the variable, either in a separate translation unit (the purpose of using extern) or in the same translation unit (if you want).
In file1.c
#include <stdio.h>
void myfunction( void );
int s=10;
void myfunction()
{
printf("This is file 1");
}
In file2.c
#include <stdio.h>
void myfunction( void );
extern int s;
int main( void )
{
myfunction();
printf("%d",s);
}
then compile (the example uses gcc
gcc -g -Wall -Wextra -pedantic -Wconversion -std=gnu11 -c file1.c -o file1.o
gcc -g -Wall -Wextra -pedantic -Wconversion -std=gnu11 -c file2.c -o file2.o
then link using:
gcc -g file1.o file2.o -o myexec
then run it as
./myexec
Of course, if your using Visual Studio, the command line statements will be slightly different

compiler isn't issue error/warning in mismatch function parameter

I have the next code :
test.c
#include "a1.h"
int main() {
int a = 8;
foo(a);
return a;
}
a1.h
void foo (int a);
a1.c
int f = 0;
void foo (int a, int b){
f=5+a+b;
return;
}
Pay attention that in a1.c foo has 1 more parameter than the prototype defined in a1.h.
The compiler isn't issue a warning or an error and so as coverity :
make all
Building file: ../src/a1.c
Invoking: GCC C Compiler
gcc -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/a1.d" -MT"src/a1.d" -o "src/a1.o" "../src/a1.c"
Finished building: ../src/a1.c
Building file: ../src/test.c
Invoking: GCC C++ Compiler
gcc -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/test.d" -MT"src/test.d" -o "src/test.o" "../src/test.c"
Finished building: ../src/test.c
Building target: test
Invoking: GCC C++ Linker
gcc -o "test" ./src/a1.o ./src/test.o
Finished building target: test
How can I defend myself in those cases ? I know that if I will add #include "a1.h" in the a1.c file I will get an error but is there a way to get an error without the "include " ?
Compiler isn't issuing a warning because it does not know that foo(int) from a1.h header and foo(int,int) from a1.c file is the same function. C++ allows functions to be overloaded, so both functions could potentially coexist. That is why C++ compiler cannot detect this problem, so you need to wait until the linking stage.
If you were compiling using C, not C++, you could have the compiler detect this condition simply by including a1.h at the top of a1.c file.
You're overloading foo. The version with only one parameter is never defined, hence you should get a linker error when using it.
How can I defend myself in those cases ?
You can't defend yourself from function overloading. Just make sure that you've got the same signature in both the header as the source file.

Linking multiple .c files

I have a C file named first.c in which I define an array and call a function which is defined in a C file named second.c. This is how first.c looks:
int main(void)
{
int array[100];
myFunc(*array);
}
second.c on the other hand looks like this:
void myFunc(int array)
{
...
}
But anytime I try to compile these, second.c gives me errors as if it had no idea about the array I passed to its function as an argument. I guess the function doesn't know that at the linking stage. I compile these like this:
gcc -O2 -std=c99 -Wall -pedantic -lm second.c -c
gcc -O2 -std=c99 -Wall -pedantic first.c -c
gcc second.o first.o -o finished
But that's just what I came up with and of course it doesn't work. I guess a Makefile would be in place, but I'm not sure how to implement it.
Your issue may lie in that the received value is not a pointer- so change void myFunc(int array) to void myFunc(int* array).

Resources