Identify version of C file - c

For a project I need to find if a c file has code that requires >=C11 or C99 compiler. Can this be done with gcc, or ctags?
Basically I need to identify the minimum version of compiler required to compile the file. I have tried different tools including ctags etc.

Use grep -- -std= Makefile
ctags: no way
If you are looking for something smarter... bad luck.

Related

How to trace specific functions/files in C?

I have already known that the GCC's argument -finstrument-functions can hook the functions and the argument -finstrument-functions-exclude-file(functions)-list can exclude some files/functions to be traced.
But now I have a lot of files to be compiled and only some of them need to be traced. I wonder if I can include some specific functions/files to be traced, such as something like -finstrument-functions-include-file(functions)-list?
Thanks a lot!
GCC does not support this out-of-the-box (it's more a task for your build system). One common hack to achieve what you want is to write a shell wrapper which replaces GCC and adds flags where needed:
$ cat path/to/fake/gcc
#!/bin/sh
FLAGS=
if echo "$*" | grep -q 'myfile1.c'; then
FLAGS=-finstrument-functions
fi
exec /usr/bin/gcc "$#" $FLAGS
$ export PATH="path/to/fake:$PATH"
If you use cmake to build your project you may benefit from adding COMPILE_OPTIONS at a specific level. Use
add_compile_options()
for directory-wide settings
target_compile_options()
for target-specific settings and
set_source_files_properties()
for file specific settings.
In your case
set_source_files_properties(
myfile1.cc PROPERTIES COMPILE_FLAGS -finstrument-functions)
Recent GCC compilers can be extended by GCC plugins.
But now I have a lot of files to be compiled and only some of them need to be traced.
You should consider writing your own GCC plugin to do that job. See also this draft report.
You may configure your build automation tool (e.g. GNU make or ninja) to help you.
At last, some of your C code (e.g. #include-ed files) could be generated. Think of meta-programming approaches (e.g. with SWIG or ANTLR or Bison or GPP or your own C code generator), perhaps using X-macros.

GCC - Adding Libraries

I want to use functions in the header files gmp.h and mpfr.h, which are in the file /opt/local/include.
But when I run gcc with -v, all of the search paths are something like /Application/Xcode.app/Contents/etc.
I have tried adding LD_LIBRARY_PATH="/opt/local/include" to .bash_profile but it doesn't work. The compiler either tells me that 'gmp.h' file not found, or Undefined symbols for architecture x86_64.
What should I do?
Converting comments into an answer.
You need to add -I/opt/local/include to compile commands (to specify where the headers are) and -L/opt/local/lib and -lgmp and -lmpfr (possibly in the reverse order — MPFR before GMP) to link commands.
That works! Would you mind explaining a little bit the logic behind this? For example if I had another header file header.h I need, how should I include it?
You include it with #include "header.h". You compile the code with -I/directory/containing/header to find the header. You specify where the library (libheader.a or libheader.dylib, since you seem to be on macOS) is too, with -L/directory/containing/lib and -lheader — or whatever is appropriate.
The -I tells the preprocessor to look in the named directory for header files, so it looks for /directory/containing/header/header.h, for example.
The -L tells the linker where to find libraries (so it looks for /directory/containing/lib/libheader.dylib etc).
The -lheader tells the linker to look for libheader.a or libheader.dylib (or local equivalents) for the libraries.
Except for the use of .dylib vs .so vs .dll vs … (and .a vs .lib vs …), the same principles apply to other systems too.
This is probably a duplicate.

Need to figure our what a specific symbol is replaced to after macro expansion [duplicate]

Let's say I have a source file with many preprocessor directives. Is it possible to see how it looks after the preprocessor is done with it?
cl.exe, the command line interface to Microsoft Visual C++, has three different options for outputting the preprocessed file (hence the inconsistency in the previous responses about Visual C++):
/E: preprocess to stdout (similar to GCC's -E option)
/P: preprocess to file
/EP: preprocess to stdout without #line directives
If you want to preprocess to a file without #line directives, combine the /P and /EP options.
Most compilers have an option to just run the preprocessor. e.g., gcc provides -E:
-E Stop after the preprocessing stage; do not run the compiler proper.
The output is in the form of preprocessed source code, which is sent
to the standard output.
So you can just run:
gcc -E foo.c
If you can't find such an option, you can also just find the C preprocessor on your machine. It's usually called cpp and is probably already in your path. Invoke it like this:
cpp foo.c
If there are headers you need to include from other directories , you can pass -I/path/to/include/dir to either of these, just as you would with a regular compile.
For Windows, I'll leave it to other posters to provide answers as I'm no expert there.
Right-click on the file on the Solution Explorer, goto Properties. Under Configuration Properties->C/C++->Preprocessor, "Generate Preprocessed File" is what you are looking for. Then right-click on the file in the Solution Explorer and select "Compile". The preprocessed file is created in the output directory (e.g. Release, Debug) with an extension .i (thanks to Steed for his comment).
You typically need to do some postprocessing on the output of the preprocessor, otherwise all the macros just expand to one liners, which is hard to read and debug. For C code, something like the following would suffice:
gcc -E code.c | sed '/^\#/d' | indent -st -i2 > code-x.c
For C++ code, it's actually a lot harder. For GCC/g++, I found this Perl script useful.
I don't know anything about Microsoft compiler, but on GCC you can use this:
gcc -E -P -o result.c my_file.h
If you want to see comments use this:
gcc -E -C -P -o result.c my_file.h
More options avaliable on this page.
Try cl /EP if you are using Microsoft's C++ compiler.
As bk1e and Andreas M. answered, the /P option for the compiler will cause it to preprocess a file. However, in my project using VS2005 and Platform Builder (for an embedded ARM processor), the project did not present an option in the dialog box (as described by Jim B) to enable that option.
I could run CL manually and add /P, but it failed because I did not know all of the appropriate command-line options that were invisibly being activated by Platform Builder during the full build. So I needed to know all of those options.
My solution was to go look in the build.log file, and find the line that executed
CL blah-blah-blah myfile.c
I copied this line to the clipboard. The "blah-blah-blah" part contained the build options, and was huge.
Back in the IDE, I right-clicked on myfile.c, chose "Open Build Window", and then in that window I pasted the build command-line, and added a "/P".
CL /P blah-blah-blah myfile.c
Done. The myfile.i file was produced, which contained the preprocessor output.
In Visual Studio you can compile a file (or project) with /P.
CPIP is a new C/C++ preprocessor written in Python. If you want a detailed visual representation of a preprocessed file, give it a shot.
CPIP is a C/C++ pre-processor implemented in Python. Most pre-processors regard pre-processing as a dirty job that just has to be done as soon as possible. This can make it very hard to track down subtle defects at the pre-processing stage as pre-processors throw away a lot of useful information in favor of getting the result as cheaply as possible.
Few developers really understand pre-processing, to many it is an obscure bit of black magic. CPIP aims to improve that and by recording every detail of preprocessing so CPIP can can produce some wonderfully visual information about file dependencies, macro usage and so on.
CPIP is not designed to be a replacement for cpp (or any other established pre-processor), instead CPIP regards clarity and understanding as more important than speed of processing.
On Windows OS, a simple one line answer to this question is to use the below command in DOS prompt to see the preprocessed file:
CL /P /C myprogram.c
This will generate a file called myprogram.i. Open it and look out for your expanded preprocessors.

Vim + YouCompleteMe + C: a minimal .ycm_extra_conf.py?

I've already got Vim with YouCompleteMe plugin (compiled with semantic support for C-family languages), which I use for Python etc. Now I'd like to try it with C (I've never developed with C before, so I've got a slightly fuzzy idea about some details, like the necessary flags.)
To use YCM's semantic completion features with C, I need to provide it a .ycm_extra_conf.py file; the YCM user guide points to YCM's own .ycm_extra_conf.py as a reference (link).
Would the following (based on the aforesaid .ycm_extra_conf.py) produce "a minimal working setup" for C (to which I could then point g:ycm_global_ycm_extra_conf):
The flags:
flags = [
'-Wall', '-Wextra', '-Werror',
'-std=c11',
'-x', 'c'
]
and FlagsForFile function without the final_flags.remove( '-stdlib=libc++' ) line.
Otherwise the example file would remain as-it-is. I believe that -isystem flags are strictly YCM-related, is that correct?
I was searching for this too and seems here we haven't get a good solution. Even this is a very old question I hope this might help someone. The following works for me,
import os
import ycm_core
flags = [
'-Wall',
'-Wextra',
'-Werror',
'-Wno-long-long',
'-Wno-variadic-macros',
'-fexceptions',
'-ferror-limit=10000',
'-DNDEBUG',
'-std=c99',
'-xc',
'-isystem/usr/include/',
]
SOURCE_EXTENSIONS = [ '.cpp', '.cxx', '.cc', '.c', ]
def FlagsForFile( filename, **kwargs ):
return {
'flags': flags,
'do_cache': True
}
By the way, that long config file by the default bothers me so much. I should give credit for this post, http://cocoaspice.logdown.com/posts/302432-youcompleteme-toss-notes
Nothing at all is perfectly valid as long as the sources can be compiled by simply clang++ -c source (c vs. c++ is decided from extension). YCM happily completes in scratch tests created in random directories for me.
The -x c is not needed. If the source has extension .c or .h, it is assumed to be C and if it has extension .C, .cc, .cpp, .cxx, .H, .hh, .hpp or .hxx it is assumed C++. Only if you have C++ headers with just .h you need -x c++-header.
Newest clang (4.9) already defaults to c11 and c++11, so you shouldn't need those either.
So you only need any -I flags and the warnings are useful.
To give you a working example, here is the configuration I'm using for Arduino projects.
https://github.com/WeAreLeka/Bare-Arduino-Project/blob/master/.ycm_extra_conf.py
In the flags I've put all the Arduino libraries provided by the IDE and needed to compile my code.
I've also written a little function to find the other libraries in my /lib dir that I'm using in my project and to add them automatically to flags. It's line 57.
It's helpful if you use a lot of libs and don't want to modify your conf file each time.
Without the -I /path/to/lib/folder you won't get autocompletion.
Hope this helps :)

Fortran g77 compiler can't recognize o.f or comment "c"

I was using Fortran g77 and experienced this problem:
c this program calculates runoff and sediment
1 2
Unrecognized statement name at (1) and invalid form for assignment or statement-function definition at (2)
Also, the compiler can recognized only .for file extension, not .f.
Does anyone know, where is the problem? I downloaded it from http://www.cse.yorku.ca/~roumani/fortran/ftn.htm.
The compiler is not recognizing that statement as a comment. As a comment it should ignore the line but it is trying parse it. Are you sure that the "C" is in the first column?
Why are you using g77? It hasn't been supported for years. gfortran is the current GNU Fortran compiler. It can compile FORTRAN 77, Fortran 90, 95 and portions of 2003 and 2008.
EDIT: Perhaps its wants an upper-case "C".
The page you have linked to states that the f2exe wrapper passes -ffree-form to the compiler:
Compilation Command
The above f2exe command is just a batch file that invokes g77, the "real" compilation command. The command:
g77 -ffree-form prog.for -oprog.exe
directs the compiler to compile the file prog.for and stores the output in the file prog.exe. The -ffree-form switch indicates free-form style (remove it if you are using the old style).
In free-form Fortran the only allowed comment format is that of a line starting with !. As a matter of fact, this is also written on the same page directly under the above text:
Comments
In free-form style, use ! for both full-line and in-line comments. In the old style, use a "C" in column-1.
If you are not using the provided f2exe wrapper, don't pass -ffree-form option when compiling fixed-form FORTRAN 77 code.
I'll assume you want to stick with this compiler.
As noted above, the problems you have come from using the F2EXE batch file, which is not very useful: first it automatically adds ".for" to the file name, so you can't compile ".f" files, and it assumes free-form syntax, which is unusual when programming in Fortran 77 (and if you want Fortran 90, find another compiler, other answers give you links).
Now, suppose you have written a program myprogram.f, and you are in a Windows command line, in the same directory where the program resides (use "cd C:\mydirectory" for example, to change)
You will compile with
g77 myprogram.f
If you use SLATEC, you use
g77 myprogram.f -lslatec
If you want to specify a name for your .exe file (default is a.exe), you write
g77 myprogram.f -o myprogram.exe
There are other useful options
g77 -O2 myprogram.f to optimize (within g77 2.95 limitations)
g77 -Wall myprogram.f to enable all compiler warnings, very useful
to find errors in your code
g77 -c myprogram.f to only compile (you get a .o file), this is
useful to compile functions and subroutines, to
later build a static library (.a file), like
libslatec.a which is given with the compiler
And to build a library, using ar.exe:
ar cru mylib.a myfunc1.o myfnuc2.o ...
Then you can use is with
g77 myprogram.f mylib.a
G77 runs in command line under Windows. You write programs in a text editor.
Notepad++ is fairly good and its free. See http://notepad-plus-plus.org/
If you have problems with compilation, maybe it comes from environment variables, so here are some precisions. You have to tell Windows where to find the G77 compiler (g77.exe).
You can follow instructions on the site where you downloaded it to change Windows' environment variables PATH and LIBRARY_PATH. It needs you install the compiler in the C:\F directory : that is, you will have C:\F\G77\bin, etc.
Slight modification to the instructions on that page :
You should set PATH to C:\F\G77\bin
And LIBRARY_PATH to C:\F\G77\lib;C:\F\SLATEC\lib
This modification to LIBRARY_PATH allows you to compile with SLATEC simply with "-lslatec" as above.
A note about the compiler. It's G77, also know as GNU Fortran 77. An old compiler, integrated with the well known GCC suite until GCC 3.4.6 (we are at GCC 4.7.2 now). And the compiler you downloaded is for version GCC 2.95.
It's a good Fortran 77 compiler, but it's not very well optimized, and of course, you don't get any support for new processor features such as Intel SSE.
Modern Fortran compilers can still understand most if not all of Fortran 77, plus all the newer features of Fortran 90 and newer standards, which are extremely useful.
It may also be interesting to know there is another place to download the same compiler (eccept there is no SLATEC), just in case the page gets destroyed :
http://www.mbr-pwrc.usgs.gov/software/g77.html

Resources