See https://man7.org/linux/man-pages/man1/gcc.1.html. Under the Synopsis section, you will see the -o option.
Regarding
Well OK, the compiler knows where to look for
stdio.h, but the executable must be linked tostdio.o, mustn't it? Where does thestdio.ofile reside?
The answer to the first question is "No". Since the answer to the first question is "No", the second question is not relevant.
The functions and variables declared in stdio.h need not be in stdio.o. They are usually in a library (.a or .so) which are found in one of the directories where the linker looks for library files.
In general, there is no rule that each .h file has a corresponding .o file. It is possible to have the functions and variables declared in a .h file to be implemented in multiple .c files that will result in multiple .o files. It is also possible to have functions and variables declared in multiple .h files to be implemented in one .c file. How these are organized varies from project to project.
Each .c file, on the other hand, has a corresponding .o file (I haven't seen any platforms where multiple .c files can be compiled to create one .o file). All the .o files resulting from compiling the .c files are linked together to create an executable.
See https://man7.org/linux/man-pages/man1/gcc.1.html. Under the Synopsis section, you will see the -o option.
Regarding
Well OK, the compiler knows where to look for
stdio.h, but the executable must be linked tostdio.o, mustn't it? Where does thestdio.ofile reside?
The answer to the first question is "No". Since the answer to the first question is "No", the second question is not relevant.
The functions and variables declared in stdio.h need not be in stdio.o. They are usually in a library (.a or .so) which are found in one of the directories where the linker looks for library files.
In general, there is no rule that each .h file has a corresponding .o file. It is possible to have the functions and variables declared in a .h file to be implemented in multiple .c files that will result in multiple .o files. It is also possible to have functions and variables declared in multiple .h files to be implemented in one .c file. How these are organized varies from project to project.
Each .c file, on the other hand, has a corresponding .o file (I haven't seen any platforms where multiple .c files can be compiled to create one .o file). All the .o files resulting from compiling the .c files are linked together to create an executable.
It indicates the output file, i.e. what your object-file or executable should be. You can see this information by doing gcc --help or man gcc.
<stdio.h> is part of the standard library, which your compiler is already linking to.
Your question
What gcc -o sample sample.c actually does
The command you have pasted triggers gcc to compile sample.c.
As a result you'll get an output/executable with the same sample.
The parameters (as -o in your example which defined the name of the output file ) are explained in the man page of gcc.
You can open it by running man gcc
I am quoting the -o section of the man page here
-o file
Place output in file file. This applies to whatever sort of output is being produced, whether it be an executable file, an object file, an assembler file or preprocessed C code. If -o is not specified, the default is to put an executable file in a.out, the object file for source.suffix in source.o, its assembler file in source.s, a precompiled header file in source.suffix.gch, and all preprocessed C source on standard output.
In General
Wikipedia explains a good amount of gcc here.
I am quoting only the start - but the complete article is worth a read and offers a lot of additional links and references
The GNU Compiler Collection (GCC) is a compiler system produced by the GNU Project supporting various programming languages. GCC is a key component of the GNU toolchain. The Free Software Foundation (FSF) distributes GCC under the GNU General Public License (GNU GPL). GCC has played an important role in the growth of free software, as both a tool and an example.
Originally named the GNU C Compiler, when it only handled the C programming language, GCC 1.0 was released in 1987. It was extended to compile C++ in December of that year. Front ends were later developed for Objective-C, Objective-C++, Fortran, Java, Ada, and Go among others.
GCC has been ported to a wide variety of processor architectures, and is widely deployed as a tool in the development of both free and proprietary software. GCC is also available for most embedded platforms,[citation needed] including Symbian (called gcce), AMCC, and Freescale Power Architecture-based chips. The compiler can target a wide variety of platforms, including video game consoles such as the PlayStation 2 and Dreamcast.
As well as being the official compiler of the GNU operating system, GCC has been adopted as the standard compiler by many other modern Unix-like computer operating systems, including Linux and the BSD family, although FreeBSD and OS X have moved to the LLVM system. Versions are also available for Microsoft Windows and other operating systems; GCC can compile code for Android and iOS.
GCC is GNU C (language) compiler. It's used to "convert" programs written in C programming language into binary executable on computer.
The syntax gcc -o sample sample.c means:
Compile the file sample.c and name the output sample.
Then you can launch your compiled program with <path_to_file>/sample, or from within the directory ./sample
The default name for compiled program is a.out, so with -o parameter you can specify your desired output name.
Here are mine:
-Wextraand-Wall: essential.-Wfloat-equal: useful because usually testing floating-point numbers for equality is bad.-Wundef: warn if an uninitialized identifier is evaluated in an#ifdirective.-Wshadow: warn whenever a local variable shadows another local variable, parameter or global variable or whenever a built-in function is shadowed.-Wpointer-arith: warn if anything depends upon the size of a function or ofvoid.-Wcast-align: warn whenever a pointer is cast such that the required alignment of the target is increased. For example, warn if achar *is cast to anint *on machines where integers can only be accessed at two- or four-byte boundaries.-Wstrict-prototypes: warn if a function is declared or defined without specifying the argument types.-Wstrict-overflow=5: warns about cases where the compiler optimizes based on the assumption that signed overflow does not occur. (The value 5 may be too strict, see the manual page.)-Wwrite-strings: give string constants the typeconst char[length]so that copying the address of one into a non-const char *pointer will get a warning.-Waggregate-return: warn if any functions that return structures or unions are defined or called.-Wcast-qual: warn whenever a pointer is cast to remove a type qualifier from the target type*.-Wswitch-default: warn whenever aswitchstatement does not have adefaultcase*.-Wswitch-enum: warn whenever aswitchstatement has an index of enumerated type and lacks acasefor one or more of the named codes of that enumeration*.-Wconversion: warn for implicit conversions that may alter a value*.-Wunreachable-code: warn if the compiler detects that code will never be executed*.
Those marked * sometimes give too many spurious warnings, so I use them on as-needed basis.
Several of the -f code generation options are interesting:
-fverbose-asmis useful if you're compiling with-Sto examine the assembly output - it adds some informative comments.-finstrument-functionsadds code to call user-supplied profiling functions at every function entry and exit point.--coverageinstruments the branches and calls in the program and creates a coverage notes file, so that when the program is run coverage data is produced that can be formatted by thegcovprogram to help analysing test coverage.-fsanitize={address,thread,undefined}enables the AddressSanitizer, ThreadSanitizer and UndefinedBehaviorSanitizer code sanitizers, respectively. These instrument the program to check for various sorts of errors at runtime.
Previously this answer also mentioned -ftrapv, however this functionality has been superseded by -fsanitize=signed-integer-overflow which is one of the sanitizers enabled by -fsanitize=undefined.
my professor advised us to use these flags when compiling :
-Wall -Weffc++ -Wextra -Wsign-conversion
and I wanted to know your thoughts on the use of flags and static analyzers, do you actually use them or does it become annoying ?
Hi,
I'm a beginner, barely scratching the surface of C at the moment. Question is, what flags do I choose for compilation? There are some "basic" like -Wall, -W, -pedantic, -ansi, -std=. GCC documentation has a ton of different flags.
Should I learn Make or CMake early to avoid retyping flags every time to compile my source files?Any help, advice are greatly appreciated.
Edit: thank you, guys. Lots of useful and interesting information. You're awesome!
The only two options there that make any sense to override are -D_FORTIFY_SOURCE and -fstack-protector, so just include -U_FORTIFY_SOURCE and -fnostack-protector, and they're effectively "gone".
You can't compile for "no architecture" (march), and getting rid of mtune is similarly meaningless. GCC has to build code for something. You're already about as generic as you can get there.
-frecord-gcc-switches, well, without that, you wouldn't know what switches were included in the first place, but if you really want to get rid of it, just use -fnorecord-gcc-switches.
-f* options are mostly boolean flags, so you can almost always turn them off by adding no at the front as I've done above.
What about doing something like
gcc -dumpspecs > myspecs.txt
Edit the specs as needed and compile with
gcc -specs=myspecs.txt