GCC on windows linux bash - c

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.

Related

How _WIN32, __linux__... preprocessor macro work?

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.)

I have not included the <unistd.h> header file, why can I still invoke the getpid() function successfully?

Code as below:
int main (int argc, char *argv[]) {
long pid = (long)getpid();
long test = pid + 1;
}
Have not included any head files, still can compile code successfully and still can run program successfully.
Why?
Environment info: Ubuntu 18.04.2 LTS, gcc (Ubuntu 4.8.5-4ubuntu8) 4.8.5
Have not included any head files,still can compile code successfully.
still can run program successfuly.Why?
Why not?
All question of whether the particular code presented conforms to the language standard notwithstanding, language non-conformance does not imply that compilation or execution must fail. Instead, you get undefined behavior, which can manifest in any manner within the power of the machine to produce, including compiling successfully and running as intended.
In your particular case, however, you are using GCC 4.8.5. The GCC 4.8 series defaults to compiling for the C90 standard, with GNU extensions. C90 allows calls to functions with no in-scope declaration, for compatibility with earlier, pre-standardization practice. That is no longer allowed in C99 or later, but many implementations nevertheless continue to accept it as an extension.
It should be understood, however, that C interprets some argument lists differently when the called function has an in-scope prototype than when it doesn't (which may be the case even for functions that are declared, because not all declarations provide prototypes). You may be able to get away with calling undeclared functions under some circumstances, but it is poor style, and if you do it enough then it will bite you at some point.
Note also that GCC 4 definitely has the ability to emit warnings about usage such as yours, even when compiling in C90 or GNU90 mode. You would be well served to turn on the -Wall option when you compile, and maybe additional warning options as well.
Normally, to use a dynamic library function you would have to link against the specified library at compile time through the -l switch, like for example gcc -lm prog.c when using the mathematic functions (from libm).
However, since it's so common, GCC always links the standard C library by default, meaning that doing gcc prog.c is actually the same as doing gcc -lc prog.c. This is always done whether you include any header or not.
The second thing that makes this work, is that GCC assumes any function that has not been declared at compile time to have the signature int func(void). In this case, the signature is quite similar to the one of the real getpid() function.
If you take a look at your compiled program with the ldd tool to show which dynamic libraries are required, you'll see that the program is linked against libc:
$ ldd prog
linux-vdso.so.1 (0x00007ffede7d0000)
==> libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f0f47018000)
/lib64/ld-linux-x86-64.so.2 (0x00007f0f475b9000)
When your program runs, it asks the dynamic loader where (at which address) to find the getpid function before calling it the first time. The dynamic loaders checks the loaded libraries, and finds a function with that name in libc, so everything seems to work without a problem.
You can tell GCC to not link against the standard library by default using the -nostdlib compiler switch, but this is not that useful in your case. The real solution is to always treat warnings about implicit function declarations as errors (-Werror=implicit-function-declaration).
If your compiler doesn't give this warning by default, I would suggest you to upgrade it to a newer version. GCC 4 is definitely not the latest version available for Ubuntu 18.
$ sudo apt update
$ sudo apt upgrade

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

How to get into C99 mode in Codeblocks10.05?

I recently realized that I am not even in C99 mode after receiving the compile error
'for' loop initial declarations are only allowed in C99 mode
I found some advice on how to get to C99 via a quick search which has told me to go to Projects -> Properties... But alas, it is greyed out and I am not sure that is even the correct way to fix it (probably not available because my file is not a project, it is a normal source file). I have also seen a lot of similar questions saying to enable C99 mode so I have looked inside the compiler flags menu, but I cannot see anything about C99. I have tried some other flags such as In C Mode, support all ISO C90 programs..., but after I set this flag, I got more errors than I had before which seem to appear whenever the compiler finds comments inside main().
Note: Please don't just say to initialize the counter outside the for loop.
Update: While trying to compile outside of codeblocks with gcc, I tried
gcc -O2 -std=C99 filename.c, but received an error:
unrecognized command line option "-std=C99"
I use 64-bit Windows 7, CodeBlocks10.05, and GNU gcc.
For future reference, type in the flag -std=c99 in settings->compiler->other options which is not case-sensitive, however when compiling in a terminal the flag is case-sensitive. Thanks chris!

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