How _WIN32, __linux__... preprocessor macro work? - c

How a C compiler like GCC defines the preprocessor macro to detect the current OS?
I looked into GCC's source code and found this builtin_define ("_WIN32"); but I'm not sure if this is where the macros are defined.

TL;DR: Basically, yes. The built-in macros are defined in a target description header file.
There is so often a Fine Manual To Read; in this case, it's the GCC internals manual. (Specifically, in the section on Run-time target specification, but don't start reading there; you'll need some context.)
There is a complete compendium of GCC documentation in case you need more information. (The internals documents are at the bottom of that page.)
(If you're comfortable using the GNU info reader and you're using a Ubuntu/Debian system, you can install the GCC documentation for your current GCC version with sudo apt-get install gcc-doc; that includes the GCC internals documentation.)

Related

GCC on windows linux bash

I am using ubuntu through windows linux bash and it happens that I am trying to compile a file and I am getting this error:
"error: ‘for’ loop initial declarations are only allowed in C99 mode".
But actually I would like not to use C99 mode but use C11 instead. How can I set my compiler to use C11 mode by default without having to pass any flags?
My GCC version is 4.8.4 running at ubuntu 14.04.3.
Thanks.
You need to specify -std=c99 or -std=gnu99 or higher to allow initial declarations in for loops. Or, just declare the variable first and use it in the for loop later.
For c11 of course, -std=c11 is the way. I don't know of a way of setting this default and perhaps there is no way. But recent gcc compilers 5.x have c11 default.
Alternative to re-building GCC yourself (complicated and error prone), update GCC (newer GCCs may not be able to compile the kernel, The kernel-developers and the GCC-developers go not always, how shall I put it ... d'accord) and typing -std=c11 every time, you can set an alias. Put the following line at the end of your .bashrc
alias gcc11="gcc -std=c11"
Let the shell re-read it's config file by source ~/.bashrc (If I remember Ubuntu correctly) and try it out.
You can call the alias gcc, too, but that might break 3rd-party makefiles.

What is the difference between the "c99" and "gcc" commands with appropriate flags?

Up until today I always read on the Internet how gcc is the best compiler for C (at least for the student level of programing, followed closely by Clang).
However in "21st Century C" Mr Ben Klemens suggests that c99 is better(?) than running gcc -std=c99 (actual line is [page 11]: everybody else switched to C99 being the default a long
time ago...)
I wasn't able to find anything on the subject of c99 compiler, so my question is:
Is there any difference between those commands and if there are, which one is better?
EDIT: The standard C99 is clearly metioned in the paragraph, however from the beginning the suggested method of compiling is the command:
gcc erf.c -o erf -lm -g -Wall -O3 -std=gnu11
However on page 11 the author states:
The POSIX standard specifies that c99 be present on your system, so the
compiler-agnostic version of the above line would be:
c99 erf.c -o erf -lm -g -Wall -O3
This seems to suggest there is a difference in those 2 commands. I wasn't able to find any additional info nor was it clear to me from the text, what the second line is exactly (no man page for c99 on my Cygwin either).
C99 is the 1999 edition of the ISO C standard. It replaced the 1990 standard, and has been (officially, at least) replaced by the 2011 standard.
What you're asking about, though, is the c99 command (I've updated your question's title to clarify that).
POSIX specifies a c99 command. The requirements are documented here. It is "an interface to the standard C compilation system".
On typical Linux systems, the c99 command /usr/bin/c99 is a small shell script that invokes the gcc commmand. It invokes gcc with the -std=c99 option. It also checks whether the user has already specified an equivalent option, so it doesn't use the same option twice. If an incompatible option has been given, such as c99 -std=c90, it terminates with an error message.
Given such an implementation, the command
c99 [args]
is exactly equivalent to
gcc -std=c99 [args]
As I mentioned above, the C99 standard has been officially superseded by the C11 standard. gcc version 5 (the current latest release is 5.3.1) has reasonably good support but not 100% complete support for C11. POSIX has not (yet) specified a c11 command.
There's nothing wrong with using the C99 standard if you don't need C11-specific features -- or even the C90 standard if you don't need C99-specific features.
In my PDF copy of the book, the discussion about using c99 instead of gcc -std=c99 seems to be on page 10, not 11.
And what is being discussed is not that c99 is "better" than gcc, but that you might be able to more easily use C99-standard compiler features with the c99 command, since you don't then need to know the specific option to enable C99 features or whether the default for the compiler is C99 or C89.
On my system, the command c99 is just an alias or link for gcc that has the -std=c99 set by default (and complains if a non-C99 standard is specified with the -std= option). I imagine that or something similar is true on most systems with a c99 compiler command.
In fact, on my system c99 is a link to a shell script:
#! /bin/sh
# Call the appropriate C compiler with options to accept ANSI/ISO C
# The following options are the same (as of gcc-3.3):
# -std=c99
# -std=c9x
# -std=iso9899:1999
# -std=iso9899:199x
extra_flag=-std=c99
for i; do
case "$i" in
-std=c9[9x]|-std=iso9899:199[9x])
extra_flag=
;;
-std=*|-ansi)
echo >&2 "`basename $0` called with non ISO C99 option $i"
exit 1
;;
esac
done
exec gcc $extra_flag ${1+"$#"}
Try c99 --version on a typical Linux box. You will get the version and name of the compiler which is gcc.
c99 is just a shortcut to the c99 compliant compiler on your machine. That way you don't have to care about the actual compiler used. POSIX also requires some common command line options the compiler has to understand. If that is gcc, it shall enable c99 compliant features. This should be identical to gcc -std=c99.
gcc provides additional features which are enabled by default [1] when called by its native name and by the -std=gccXX option in addition to the CXX standard. For older versions, some of these extensions became part of the next C standard either directly or with slightly different syntax. A typical and appreciated extension for C90 is support for C++-style line-comments:
// this is not allowed in pure C90
For c99/gnu99 things are less obvious, but might still add some usefull features.
On other POSIX systems, e.g. Unix, you may find a different compiler. It shall still be available by the name c99.
Note that the current and only valid C standard is C11 since 2011. So if you want to use the new features (e.g. atomics, thread-support), you have to deviate from the pure POSIX-path. Yet it is likely POSIX might be updated some day.
[1] The default version of the C standard depends on the version of gcc. pre5 used C90, while gcc 5.x uses C11.

How to use C only features in latest compilers?

I am using codeblock 13.12 and it uses mingw (GCC 4.7 & 4.8 Series)
It supports call by reference (func1(int &a)) eventhough I am selecting C project and not CPP project. If I am not mistaken, there is no concept of call by reference in C and everything is call by value even if it is making use of pointers.
My question is how to use C only features? Any settings for this? I saw that in toolchain it is using mingw32-gcc.exe for c compilations.
How to know which compiler version (Like C11, C99 etc) it is really using?
Name your files with an extension of .c. And definitely not .cc or .cpp
Compile with gcc as the command line, not g++
And if in doubt, use the -std= command line parameter to force the flavor of C you want (e.g. -std=C90, -std=C99, or even -std=C11 ). There's also -ansi.
Also, a cheap and dirty way to validate if your code is getting compiled as C and not C++ is to add this block of code within your source code. If it's C++, then the compiler will generate an error.
#ifdef __cplusplus
int compile_time_assert[-1];
#endif

C compiler preprocessor output

C compilers supports generating the preprocessor output file with .i extension.
As far as I know, this is true for Microsoft (Visual Studio), ARM, Keil and some GNU compilers.
They usually use the compiler switch -E or -P for that.
There's also the compiler switch -C to retain comments.
Is the creation of preprocessor files a standard in ANSI-C, or is this compiler specific?
Is the option -C also a standard?
EDIT:
To be more precise: This is about the support for creation of the .i file, not the compiler switch syntax or names.
It is not standardized in the ISO C standard.
However most compilers seem to have -E for generating prepro output. This is reasonable as the prepro output is often very useful for debugging.
Here is a list of compilers I checked:
gcc
pcc
clang
ctc (TriCore)
Tasking C166
Wind River (DIAB)
All these compilers allow writing the prepro output to any file (with any extension). The .i is definitely not standard.
The option -C for retaining comments seems to be rather specific.
The C programming language standard doesn't specify anything about how compilers are invoked.
It might be an "ad hoc" standard, but it's not something that is controlled in any official fashion "globally". There are local standards, such as POSIX that can specify things like these, but that would of course not cover compilers implemented for non-POSIX environments.

Check GCC version in runtime

I need to find out the available (installed in the system) GCC version (Major and minor) inside the execution of a c program (in runtime). Meaning, programatically extract the version of the available gcc (same as if I was in a shell and typed gcc --version, but in a c program).
The __GNUC__ and __GNUC_MINOR__ are only useful in compile time and I've found the gnu_get_libc_version() function from gnu/libc_version.h, but it only gets me the libc version and I need the GCC version. If there is something similar for GCC it would be great...
I would really like to avoid calling a shell command to do this.
There is a simple way:
$ gcc -dumpversion
4.6
Invoke the gcc shell command with the parameter --version; it's the correct way to do this. See popen() to do that.
Or you can invoke GCC with to compile a program which prints the values for __GNUC__ and __GNUC_MINOR__. But that will not work if the GCC in question is configured for cross compilaton.
Alternatives would be to search the binary for version strings and hoping that you get the right one, that the format doesn't change and that the version string is distinct enough for you to recognize it with enough confidence.
In 1.5 words: Don't.
I need to find out the available (installed in the system) GCC version (Major and minor)
What are you going to do with the information?
You can't get a meaningful answer to your question, because
The user may not have any GCC installed in /usr/bin
May have 5 different versions installed elsewhere on the system
May have a version in /usr/bin which pretentds to be gcc-X.Y, but is actually gcc-Z.W, or Clang, or icc, etc.
But if you insist on getting a meaningless answer, popen("gcc --version") and parse the resulting output.

Resources