Is there a command that tells the compiler to print its version? - c

I need to upload my assignments to an online compiler, I was told it's GCC but I'm getting segfault on the online compiler but not when compiling with VS or on linux's GCC.
Is there a way to make compiler print what compiler is it and its version?

usually there isn't a single command.
you can try and check compiler defined macros.
cmake does this, it has a wide array of checks to detect compiler versions.
It compiles code and prints a "vendor string" based on preprocessor symbols.
here is for instance the code for gcc: https://github.com/Kitware/CMake/blob/master/Modules/Compiler/GNU-DetermineCompiler.cmake
since clang is drop in replacement for gcc you might also want to check the macros used here:
https://github.com/Kitware/CMake/blob/master/Modules/Compiler/Clang-C-FeatureTests.cmake
Edit:
So a running C example would do the following:
#include <stdio.h>
int main(int argc, char **argv) {
#ifdef __clang_major__
printf ("clang detected version %d.%d\n", __clang_major__, __clang_minor__);
#endif
#ifdef __GNUC__
// note that clang 3.7 declares itself as a gcc 4.2"
printf ("gcc detected version %d.%d\n", __GNUC__, __GNUC_MINOR__);
#endif
}
output for clang:
$ clang main.cc
$ ./a.out
clang detected version 3.7
gcc detected version 4.2
output for gcc:
$ gcc main.cc
$ ./a.out
gcc detected version 4.8

Related

gcc linking two files not working in macOS

For my compiler course, I'm following the Incremental Approach to Compiler Construction by Abdulaziz Ghuloum with the accompanying tutorial. At some point, we have the following two .c files:
runtime.c
#include <stdio.h>
int main(int argc, char** argv) {
printf("%d\n", entry_point());
return 0;
}
ctest.c
int entry_point() {
return 7;
}
The author then runs the following commands:
$ gcc -Wall ctest.c runtime.c -o test
[bunch of warnings]
$ ./test
7
$
But when I run $ gcc -Wall ctest.c runtime.c -o test I get the following error:
runtime.c:9:20: error: implicit declaration of function 'entry_point' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
printf("%d\n", entry_point());
I want to be able to compile and link my two .c files the same way the author did using gcc, but it keeps throwing me that error. I've been doing some research but the same command ($ gcc file1.c file2.c -o combined) keeps coming up. Help would be appreciated.
I'm running this on MacOS Monterey 12.6 and doing gcc --version displays:
Apple clang version 14.0.0 (clang-1400.0.29.102)
Target: x86_64-apple-darwin21.6.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
Thanks in advance
On macOS, the default compiler is clang, not gcc. The later is just a symlink to clang so that's something to keep in mind.
Clang sees the call to entry_point() in runtime.c and doesn't know it yet. Traditional C for such an undefined function is to assume it returns int and does not accept arguments. But Clang goes the safe route by default and instead of just warning about it, treats this as an error since most of the time this assumption is just false and may cause runtime issues.
You have multiple options:
Add a header file that defines int entry_point(void); and #include it in your runtime.c.
Add the line int entry_point(void); near the top of your runtime.c.
Pass -Wno-error=implicit-function-declaration to the compiler.

How do I compile code using Clang with the MinGW C/C++ Library? (Particular issue with float.h)

I have a simple program which I can successfully compile with clang, using MinGW's C/C++ Library:
#include <stdio.h>
int main(int argc, char **argv) { printf("Hello world!\n"); return 0; }
I am able to compile this with mingw-gcc successfully:
$ gcc test.c -o test
$ ./test
Hello world!
I am also able to compile it successfully using clang+mingw:
$ clang test.c -o test -target
$ ./test
Hello world!
However, if I make a small change to my program (include float.h), it continues to compile with gcc but no longer compiles with clang:
#include <stdio.h>
#include <float.h>
int main(int argc, char **argv) { printf("Hello world!\n"); return 0; }
$ gcc test.c -o test
$ ./test
Hello world!
$ clang test.c -o test -target x86_64-pc-windows-gnu
In file included from test.c:2:
In file included from C:\llvm\built\lib\clang\8.0.0\include\float.h:45:
C:\mingw64-8.1.0\x86_64-w64-mingw32\include\float.h:28:15: fatal error: 'float.h' file not found
#include_next <float.h>
^~~~~~~~~
1 error generated.
Is there some configuration issue with clang or some missing command line argument? Googling around a bit, it appears that the order of paths when including float.h is important, but this is all supposed to be handled internally by the clang driver.
The older binary releases of MinGW-w64 have an incompatibility with Clang 8.0+'s float.h. To fix this, copy this specific revision of float.h into the correct location and use it.
I think that it would be advisable to pass this issue on to one of the clang developers.
Comparing the previous release 7.1.0's float.h to the one in 8.0.0 shows only a few differences. The first one I myself would be asking about, is why they change to the header guard from __FLOAT_H to __CLANG_FLOAT_H.
Have a play around changing the 8.0.0 header guard and see what happens.
Edit: Did a bit more searching. The MinGW-w64 developers know of this change since August 2018. Add or adapt the patch from https://sourceforge.net/p/mingw-w64/mailman/message/36386405/ to your MinGW install may sort it out.
Edit 2: Something that I have not used for a while is my MSYS2 install of MinGW. It shows g++.exe (Rev1, Built by MSYS2 project) 8.2.1 20181214. This has the applied patch to line 27 of float.h.
#if !defined(_FLOAT_H___) && !defined(__FLOAT_H) && !defined(__CLANG_FLOAT_H)
While the source forge download of MinGW-w64 8.1.0 has it shown as
#if !defined(_FLOAT_H___) && !defined(__FLOAT_H)
Note: I'm also sure that MSYS2 uses a rolling release update, but I would have to check on that. It's not something that I use on a regular basis.
Edit3: MSYS2 looks like it's a rolling release. Latest versionis 9.1.0.
My opinion unless you need a stand alone MinGW, then go with MSYS2 with the latest updates. Just trying to patch one of the old versions may work, but there could be other issues that my show themselves. If you do need a stand alone version, then I think that the only option would be to build MinGW-w64 directly from source.
NOTE: I would have added comments to the above discussion, but being new I'm not allowed yet.
EDIT 4:
NOTE: The third party multilib toolchains are more than likely built with sjlj exceptions as default. See https://stackoverflow.com/a/17968530/11879567 on how to check.
Edit 5:
Hopefully this is the last edit I will be making.
Checking out the MinGW-w64 forums to see if anyone had asked when the next official release was due. I came across someone who did ask about when 8.2 was to be released. I got the impression that you could be in for a very long wait for any new MinGW-w64 release.
https://sourceforge.net/p/mingw-w64/discussion/723797/thread/ea9a5b00fb/
SIDE NOTE:
As I have found out when dealing with Clang, you are always going to have one issue or another with it, either with MinGW or Visual Studio.

Coverity Scan fails to build <stdlib.h> with _GNU_SOURCE defined

The Coverity Scan Build Tool fails to compile any C file that includes <stdlib.h> on Ubuntu 18.04 when _GNU_SOURCE is defined:
$ cat > main.c
#include <stdlib.h>
int main() {
}
$
$ gcc -D_GNU_SOURCE=1 -o main main.c
$
$ /opt/cov-analysis/bin/cov-build --dir cov-int gcc -D_GNU_SOURCE=1 -o main main.c
Coverity Build Capture (64-bit) version 2017.07 on Linux 4.15.0-20-generic x86_64
...
[WARNING] Emitted 0 C/C++ compilation units (0%) successfully
...
$
The same build works perfectly on Ubuntu 16.04 or without _GNU_SOURCE defined:
$ /volatile/local/cov-analysis/bin/cov-build --dir cov-int gcc -o main main.c
Coverity Build Capture (64-bit) version 2017.07 on Linux 4.15.0-20-generic x86_64
...
Emitted 1 C/C++ compilation units (100%) successfully
...
$
How to get Coverity Scan to build C sources with _GNU_SOURCEdefined on Ubuntu 18.04?
For those interested file cov-int/build-log.txt can be found here:
https://gist.github.com/DimitriPapadopoulos/0dcd9018eed26401cc6095087d9cc1d5
After contacting Coverity support, it appears this is known bug. They suggested I work around it by switching from the default Ubuntu 18.04 compiler (GCC 7) to the previous version (GCC 6):
sudo apt install gcc-6
Indeed _Float32, _Float32x, _Float64, _Float64x and _Float128 were introduced in GCC 7.
Coverity is failing to define the types GCC would define, but then it's claiming to be GCC anyway. Here's a workaround: https://gist.github.com/vathpela/0cede6d6eb5b0ec0791c6afc4282c340#file-fix_coverity-h
Just be sure you do:
#include "fix_coverity.h"
before stdlib.h gets included, whether directly or indirectly.

Resolve TCC warnings on macOS

I'm looking for a C interpreter to use while making a simple C utility to avoid compiling all the time. I installed TCC as suggested here but I get warnings and errors. How do I run TCC correctly?
$ tcc -run hello.c
.../usr/include/sys/cdefs.h:81: warning: #warning "Unsupported compiler detected"
#if !defined(__GNUC__) || __GNUC__ < 4
#warning "Unsupported compiler detected"
#endif
Setting __GNUC__ causes an error later on:
tcc -D__GNUC__=4 -run hello.c
.../usr/include/i386/_types.h:98: error: ';' expected (got "__darwin_va_list")
#if (__GNUC__ > 2)
typedef __builtin_va_list __darwin_va_list; /* va_list */
#else
typedef void * __darwin_va_list; /* va_list */
#endif
My environment:
~$ gcc --version
Apple LLVM version 9.0.0 (clang-900.0.39.2)
Target: x86_64-apple-darwin16.7.0
If TCC is not fit for macOS, please suggest a C interpreter that plays nicely.
For sure one that will work is CERN's Cling or any other based on LLVM/Clang, since that is what Apple uses in macOS.
The block comment immediately above the line your first message complains about is
/* This SDK is designed to work with clang and specific versions of
* gcc >= 4.0 with Apple's patch sets */
#if !defined(__GNUC__) || __GNUC__ < 4
#warning "Unsupported compiler detected"
#endif
which is pretty clear - you do need gcc or clang. Fortunately both of those compilers are really easy to install - use https://www.macports.org.
I wouldn't bother with a C interpreter - it's not an interpreted language.
First of all, tcc is not an "interpreter" it is a very fast compiler that can be used to compile and run your C code as if it were script.
Secondly, the "Unsupported compiler detected" warning is just that, a warning. I get that warning all the time and my code still compiles and runs no problem. If the warning bothers you, you can simply run tcc with the -w option to suppress the warnings (probably only advisable if you are re-running a file that you already know has no issues).
For example, if you are running the C code as if it's a script using the tcc shebang line, you can change it to this
#!/usr/local/bin/tcc -w -run
There can be a couple of other issues when running tcc on macOS. The main one is missing include files. On macOS the include files may not be installed to /usr/include/. See this question for the fix. Once Xcode had properly installed the headers, I still needed to update my environment variable to get tcc to find them.
export C_INCLUDE_PATH="/usr/include:$C_INCLUDE_PATH"
You can see where tcc is looking for header by running tcc -vv.

MinGW doesn't produce warnings

I have successfully installed MinGW on a Windows 7 32bit machine, and have tried to compile a simple program using either the command line or the MinGW console.
The code has an intentional error in a printf statement:
#include <stdio.h>
#include <stdlib.h>
int main( void )
{
printf("%d\n" , 3.14 ) ;
return 0 ;
}
The command gcc -Wall hello.c gives a correct warning: hello.c:7:2: warning: format '%d' expects argument of type 'int'...
But the command gcc -std=c99 -Wall hello.c doesn't give any warning.
Both create an executable a.exe ( that runs and gives the same result ).
(Interestingly a command gcc -std=gnu99 -Wall hello.c gives the warning.)
I don't know if this is a bug, or did the installation go wrong somehow, but both seem unlikely since the compiler works and successfully compiled a larger project( but the same warning of course omitted when using -std=c99 ).
I must be missing some information.
(ps: If someone has a new MinGW install, please test this.)
gcc version 4.8.1 (GCC)
Update 1:
Defining _GNU_SOURCE before including stdio.h removes the warning even with gcc -Wall hello.c.
Update 2( might be less relevant ):
Compiling
printf("%lf\n" , 3.14 ) ;
-std=c99 flag outputs: 0.000000
-std=gnu99 outputs: 3.140000
And compiling:
printf("%f\n" , 3.14 ) ;
-std=gnu99 and -std=c99 output: 3.140000
Update 3:
Functions that seem to be affected are: printf, fprintf, snprintf, sprintf.
The problem with the lack of warning when using the std=c99 option looks like it's because MinGW 4.8.1 preprocesses stdio.h a little different for the printf() family of functions when -std=c99 is used compared to when -std=gnu99 is used.
Note: I'm looking at MinGW 4.8.1 from TDM - I think other distributions might differ in these details.
MinGW has had some compatibility issues with formatting floating point values because of its historic reliance on msvcrt.dll for the C runtime and the fact that MSVC uses a 64-bit representation for long double while gcc uses a 96-bit (or 128-bit on x64) representation. See gcc: printf and long double leads to wrong output. [C - Type conversion messes up] for some details. More recent versions of MinGW have provided thier own implementation of the printf() family of functions (with a __mingw_ prefix on the name) in libmingwex.a to solve those problems.
The header files _mingw.h and stdio.h configure whether or not the libmingwex.a implementations or the msvcrt.dll implementations will be used.
It appears that if ANSI compliance is requested, MinGW will use the libmingwex.a implementations (there are a number of other ways to get this configuration too - look at the headers for details). Wiring up a user call to printf() to the __mingw_printf() implementation in libmingwex.a is done by stdio.h defining a static inline implementation of printf() that is a thin wrapper around a call to __mingw_vfprintf(). Apparently the -Wformat doesn't get applied to versions of printf() family functions that the compiler doesn't believe to be part of the library (a reasonable assumption - the compiler doesn't really know anything about those functions). This problem can be fixed by applying the appropriate function attribute (for example: __attribute__ ((format (printf, 1, 2)))) to the static inline wrapper functions.
The other problem you found, where printf("%lf\n", 3.14) prints 0.000000 when using std=c99, looks to be a bug in the libmingwex.a implementation of __mingw_vfprintf(). It seems that __mingw_vfprintf() mistakenly interprets "%lf" to mean the argument is a long double. I'm not too surprised by that - I always have to look up whether %lf means double or long double.

Resources