3

First, is it possible to edit GCC command line settings so that I don't have to compile with the -std=c99 flag every time?

Secondly, why is c99 not the default behavior to begin with? Compiling with c99 allows for certain modern programming conventions such as creating and initializing the index variable in a for loop.

for(int i = 0; i < 10; i++) {...

Without the c99 flag, this would not be possible and i would have to be declared externally on its own line which I think is silly. Why wouldn't GCC just compile with C99 by default? (Legitimately curious, not complaining. Please, no bashing)

Thanks.

sepp2k
  • 363,768
  • 54
  • 674
  • 675
Vee
  • 729
  • 10
  • 27
  • 6
    I suppose you could do `alias gcc="gcc -std=c99"`. – Elliott Frisch Oct 28 '14 at 02:03
  • 1
    Technically [C99 support](https://gcc.gnu.org/c99status.html) is not complete. The [standards page](https://gcc.gnu.org/onlinedocs/gcc/Standards.html#Standards) says: `The default, if no C language dialect options are given, is -std=gnu90; this is intended to change to -std=gnu11 in some future release.` –  Oct 28 '14 at 02:04
  • @remyabel: Yes, and whenever the next revision comes out they will update that noble aim. – Deduplicator Oct 28 '14 at 02:08
  • 6
    Using a makefile is a good way to hide all the details. Then you just type "make". – Charlie Burns Oct 28 '14 at 02:12
  • @remyabel: That looks like an answer. – mafso Oct 28 '14 at 02:33
  • 1
    @mafso Not really. It appears the manual contradicts itself. [C Dialect Options](https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html#C-Dialect-Options) says `‘gnu1x’ GNU dialect of ISO C11. This is the default for C code.`. –  Oct 28 '14 at 02:38
  • Wait a year or so until GCC 5.0 comes which will default to gnu11. – Z boson Oct 28 '14 at 12:45

4 Answers4

10

If you REALLY want to add -std=c99 every time, you can modify the so-called "spec file" which is a config file for the gcc command. Note that the gcc command is actually a compiler driver which only invokes a compiler in a narrower sense (the latter is ccl or cc1plus in the case of GCC toolchain.)

Modifying the specs file is a bit tricky nowadays because it exists only inside the binary file of the gcc command by default. This is because very few people wanted to modify it for their own purpose.

Find paths at which the gcc command tries to find any spec files in this way,

$ strace -e file gcc 2>&1 | grep specs
access("/usr/lib/gcc/x86_64-linux-gnu/4.6/specs", R_OK) = -1 ENOENT (No such file or directory)
access("/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../x86_64-linux-gnu/lib/x86_64-linux-gnu/4.6/specs", R_OK) = -1 ENOENT (No such file or directory)
access("/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../x86_64-linux-gnu/lib/specs", R_OK) = -1 ENOENT (No such file or directory)
access("/usr/lib/gcc/x86_64-linux-gnu/specs", R_OK) = -1 ENOENT (No such file or directory)

and then create a template file at one of the above locations by dumping the built-in specs file:

$ sudo bash -c 'gcc -dumpspecs > /path/to/specs'

At this point, the output from gcc -v should change from this

$ gcc -v
Using built-in specs.
(...snip...)

to something like

$ gcc -v
Reading specs from /usr/lib/gcc/x86_64-linux-gnu/4.6/specs
(...snip...)

Now you need to modify the specs file according to your need. The syntax is indeed cryptic but you can use your imagination. Hint: you should see something like

*cpp_options:
%(cpp_unique_options) %1 %{m*} %{std*&ansi&trigraphs} %{W*&pedantic*} %{w} %{f*} %{g*:%{!g0:%{g*} %{!fno-working-directory:-fworking-directory}}} %{O*} %{undef} %{save-temps*:-fpch-preprocess} %(ssp_default)

Look at this part:

%{std*&ansi&trigraphs}

This is where -std=c99 is expanded into before the gcc command constructs the full command line for the preprocessor cpp. You should be able to insert -std=c99 just before it so that it works as your own default value for the -std option. Do the same for *cc1_options which is actually more important for your purpose.

nodakai
  • 7,773
  • 3
  • 30
  • 60
5

I do not know the answer to this, but you should just use a makefile.

Very simple makefile:

CC = gcc
CFLAGS = -g -Wall -std=c99
OBJECTS = *.c  #Source files
NAME = FILENAME  #Desired filename
TODELETE = $(NAME) *.o # the *.o should be the same as the objects
LIBS = NECESSARY_LIBS #remove line if no external libraries needed

mt-collatz : $(OBJECTS)
<INSERT TAB>$(CC) $(CFLAGS) $(OBJECTS) -o $(NAME) $(LIBS)

.PHONY: clean
clean:
<INSERT TAB>rm -f $(TODELETE)

Type make to compile, make clean to remove compiled objects. Remove comments with # sign, and add a tab where it says INSERT TAB since I don't know how to do it on SO.

You don't actually have to remove the *.c and *.o in OBJECTS and TODELETE, but it will complain if you ever end up with more than one file with a main function.

Christopher Schneider
  • 3,745
  • 2
  • 24
  • 38
2

You can add this to your ~/.profile or similar on your platform:

CFLAGS="$CFLAGS -std=c99"

Then Make and similar tools should pick it up every time.

As for why it's not the default: backward compatibility!

John Zwinck
  • 239,568
  • 38
  • 324
  • 436
1

The good way is to use a  Makefile like answered by Christopher Schneider. See also this example.

You could also have a shell script (in your $PATH, before /usr/bin), perhaps even named gcc (i.e. $HOME/bin/gcc with $HOME/bin put before /usr/bin/ in your $PATH, see your ~/.bashrc), which invokes /usr/bin/gcc with the desired option. For interactive use you could also alias the gcc command.

At last, GCC is using spec-files. You could change your system's spec file to add specific options (for cc1). I'm not sure it is a good idea.

Next version (5.0) of GCC will default to C11.

Community
  • 1
  • 1
Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547