5

Is there a way of telling gcc to use the c99 standard when compiling c files as a default? I want to avoid giving it the -std=c99 parameter all the time. I assume I can do this by creating an alias in the .bashrc file, but seems to be rather inelegant.

bsky
  • 19,326
  • 49
  • 155
  • 270
  • Possible duplication of - http://stackoverflow.com/questions/5060799/c99-not-default-c-version-for-gcc – Leeor Jan 18 '14 at 15:30
  • Actually, aliases in `bashrc` are an elegant (and standard) solution for many "customization" problems of this sort, though I wouldn't recommend masking the name `gcc`--you should name your alias something else. (E.g. `ll` is commonly aliased to `ls -lA`.) – Kyle Strand Sep 09 '15 at 16:08

4 Answers4

6

You may call c99 instead of gcc (wrapper for gcc, if it's available on your system) or try to modify your gcc spec file. More information here: http://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Spec-Files.html

jbgs
  • 2,795
  • 2
  • 21
  • 28
  • c99 is effectively a prerequisite on all POSIX platforms. But beware, that it mustn't necessarily point to the same version of gcc. Namely on OS X, c99 is a completely obsolete version of gcc. – Jens Gustedt Jan 18 '14 at 17:05
2

Here's an unexpected answer. Use a Makefile!

Pros:

  • Simply type make to build
  • All options are automatically handled in the build process.
    While you're at it, go ahead and enable all warnings, as is good to do. See this.
  • Easy to scale up to multiple source files
  • Can handle multi-step builds involving different tools

Cons:

  • Another tool to learn, another thing to get wrong.

Consider this source:

#include <stdio.h>

int main() {
    printf("Hello!\n");
    int x = 4;
    printf("%d\n", x);
    return 0;
}

You could make a Makefile like this:
(Disclaimer, I don't actually know how to write them)

CC=gcc
CFLAGS=-Wall -pedantic -std=c99
LDFLAGS=
SOURCES=$(wildcard *.c)
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=hello

.PHONY: clean

all: $(SOURCES) $(EXECUTABLE)

$(EXECUTABLE): $(OBJECTS) 
    $(CC) $(LDFLAGS) $(OBJECTS) -o $@

.cpp.o:
    $(CC) $(CFLAGS) $< -o $@

clean:
    rm -f *.o $(EXECUTABLE)

And it builds for me.

Likewise, if you remove the -std=c99, it shouldn't be valid C89 code, and indeed, typing make brings up the build error.

Community
  • 1
  • 1
Prashant Kumar
  • 20,069
  • 14
  • 47
  • 63
  • "Another tool to learn, another thing to get wrong....Disclaimer, I don't actually know how to write them" No offense, but I think you've severely undermined your own answer with those statements. Build systems are extremely important for non-trivial projects, but (1) raw Make is (IMO) a pretty terrible choice of build systems, and (2) build systems aren't really necessary or helpful for single-file "sandbox"-style compilation. – Kyle Strand Sep 09 '15 at 16:12
  • Actually, it turns out that just defining `CFLAGS` (and doing nothing else in the Makefile) is an okay solution here; `make` will auto-generate targets using the default args (I did not realize this). See http://stackoverflow.com/a/32485029/1858225 – Kyle Strand Sep 09 '15 at 17:52
1

Custom compilation suggests you have at a working knowledge of compilers, standards, and basic flags / options. For that reason, I suggest you set shell variables in your .bashrc, .tcshrc, etc., and use them on the command line.

Since the choice of dialect can have an effect on linking: CC="gcc -std=c99", lets you invoke separate compilation commands using $CC -c -O2 ... foo.c, and is also picked up as the default for configure scripts, etc. Of course, you can always override a configure script with CC="gcc -std=c90" or CC="clang". The same applies to a preferred CFLAGS value, e.g.,

CFLAGS="-pipe -W -Wall -O2 -march=core2"

Allows for $CC $CFLAGS -c foo.c commands, and both environment variables are used by default with configure scripts, unless you explicitly override them. I think this is more useful than aliases. But perhaps I've just grown used to my own setup:)

Kyle Strand
  • 15,941
  • 8
  • 72
  • 167
Brett Hale
  • 21,653
  • 2
  • 61
  • 90
  • I've fixed a couple of your variable assignments, which needed quotes to be handled properly in Bash (and probably most or all other standard shells). I think an alias would be a good solution when used *in conjunction with* your suggestion of variable assignments: `alias cc="$CC $CFLAGS"`. – Kyle Strand Sep 09 '15 at 16:15
0

Both of the proposed solutions are, in my opinion, almost what you want, but neither quite gets there.

Makefile solution

As seen here, by defining variables in your Makefile but not defining targets, you can use the make command like a customized pass-through to GCC. So if you create a Makefile in your "sandbox" directory (or wherever you're compiling outside of a real build system) and define the C*FLAGS vars, you'll essentially get what you want. An example Makefile:

CFLAGS=-Wall -std=c99
CXXFLAGS=-Wall -std=c++14

Now, make foo will turn foo.c into an executable called foo.

If you want to do this trick in multiple directories, put your makefile in a known location--say, ~/sandbox--and create the following alias (or something like it) in your .bashrc:

alias usestdmake="ln -s ~/sandbox/Makefile"

Then you can quickly compile a single file anywhere on your machine:

usestdmake
make foo

This has the added advantage of giving the output executable an appropriate name (foo in this case). It has the disadvantage of disabling tab-completion for your compile command (make fo<tab> does nothing, at least on my system).

Pure bashrc solution

The CC/CFLAGS variables mentioned in Brett Hale's answer are fairly standard, so it might be a good idea to define them in your bashrc. You can then use these variables inside of aliases.

In your .bashrc:

CFLAGS="-Wall -std=c99"
CC=gcc
# Use single-ticks to ensure that the variables are evaluated when the alias is evaluated.
alias mycc='$CC $CFLAGS'

On the command line:

cc foo.c    # Compile with default CFLAGS
CFLAGS="$CFLAGS -O2" cc foo.c    # Compile with modified CFLAGS
Community
  • 1
  • 1
Kyle Strand
  • 15,941
  • 8
  • 72
  • 167