Is there a way to have g++ check for C++98 syntax when compiling but at the same time compile as if no -std=
has been given ? My goal is to make sure that my source code stays C++98 but I don't want to prevent g++ from using any newer optimisation or trick. For the moment, I compile my projet twice, once with CXXFLAGS=-std=c++98
and one with a final empty CXXFLAGS
for release.
It looks like gcc 5 will have -Wc90-c99-compat
and -Wc99-c11-compat
, that something in that direction.
You will have to run the compiler twice, but you can save compiletime
on the -std=c++98
pass and avoid generating unwanted object files by specifying syntax-checking only. You do that by
passing the option -fsyntax-only
.
You'd also need to modify your make
to skip linkage for C++98, as there'll be nothing to link.
Probably the most efficient way you could do this is with a make
on the
following lines:
.phony: all clean
SRCS = foo.cpp
FLAT_SRCS = $(patsubst %.cpp,%.ii,$(SRCS))
OBJS = $(patsubst %.ii,%.o,$(FLAT_SRCS))
%.ii: %.cpp
g++ -std=c++98 $(CPPFLAGS) -E $< > $@ && g++ -std=c++98 -fsyntax-only $@
%.o: %.cpp
%.o: %.ii
g++ -c -o $@ $(CPPFLAGS) $(CXXFLAGS) $<
all: foo
foo: $(OBJS)
g++ -o $@ $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(LDLIBS)
clean:
rm -f $(OBJS) $(FLAT_SRCS) foo
Here, the %.ii: %.cpp
rule will first just preprocess the .cpp
to the .ii
,
then pass the already preprocessed source to a C++98 syntax-checking pass,
which produces no new file.
The empty %.o: %.cpp
rule overrides the implicit rule that would otherwise
cause the .cpp
to be compiled to .o
, and it is replaced with the %.o: %.ii
rule to compile the .ii
. g++ recognises .ii
as denoting already-preprocessed
C++ source code, so it will not preprocess the source a second time.
Code is only preprocessed once, and object code is only generated once.
The linkage is as usual. Provided the C++98 syntax check passes, a make
will look like:
$ make
g++ -std=c++98 -E foo.cpp > foo.ii && g++ -std=c++98 -fsyntax-only foo.ii
g++ -c -o foo.o foo.ii
g++ -o foo foo.o
rm foo.ii
You'll note that make
automatically deletes the preprocessed .ii
, which is fine:
it's just a conduit between the .cpp
and the .o
.
All that being said, I side with @Matt McNabb's observation that you have nothing to
gain by this! Given your code is C++98, the compiler won't optimize it any better
when instructed that it must be C++98 than when not. By time GCC gets to the
optimization stage of its business, it no longer cares what kind of source code
it started off with.
You may be supposing that -std=c++98
, when given say to g++ 4.x, causes the
whole compiler to behave as if was g++ 2.x. Not so. It's still g++ 4.x, with the
g++ 4.x optimization tech, etc., just operating by the language definition of C++98.
There would certainly be a point in this if your code for some reason had to pass,
as C++98, on some older compiler than your release compiler, and in that case you
would need to distinguish the compilers in the makefile. But apparently this is not the
case. You might as well just compile conventionally with -std=C++98