I may have found a bug in gcc. I couldn’t find anything related to this online so I want to know if anyone seen this before.
I am using “Ubuntu 16.04.0 LTS” with:
gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.6)
, but this problem can be reproduced on later gcc versions as well, gcc-6 and gcc-7.
Here https://github.com/mihaipop11/gcc-linux you can find a link to a github repo containing all the sources but I’ll also explain this below.
How to reproduce:
We have this nice little program with these files:
// main.cpp #include <iostream> #include INCLUDE_FILE int main() { std::cout << "Works this time" << std::endl; }
and a header file inside a folder, let’s say named include
, doesn’t matter that is empty, this is only for demonstration purposes.
// include.hpp //empty header
Overall the structure looks like this:
<dir> ├── main.cpp └── include └── include.hpp
Compilation step:
I analysed two cases and the bug appears in the second one.
First case:
The <dir>
folder name which holds the files should be named anything but something that contains the string linux
. ex: test-notlinux
Overall the structure looks like this:
test-notlinux ├── main.cpp └── include └── include.hpp
Now, cd test-notlinux
and try to compile the sources:
g++ "-D INCLUDE_FILE="${PWD}/include/include.hpp"" main.cpp g++ "-D INCLUDE_FILE=<${PWD}/include/include.hpp>" main.cpp
Result: Both commands work as expected. No issue here.
Second case:
The <dir>
folder name which holds the files contains the string linux
. ex: test-linux
Overall the structure looks like this:
test-linux ├── main.cpp └── include └── include.hpp
Now, cd test-linux
and try to compile the sources:
// first command should work g++ "-D INCLUDE_FILE="${PWD}/include/include.hpp"" main.cpp // but this ... g++ "-D INCLUDE_FILE=<${PWD}/include/include.hpp>" main.cpp
Result: The second command apparently replaces the linux
string from the dir name with 1
Output: /tmp/test-1/include/include.hpp: No such file or directory
Does anyone know something about this?
Advertisement
Answer
First thing is that linux
is a macro defined to 1
. In <> case the macro is expanded while in “” case, the token is a string.
Second thing is that linux
is a defined only when using the GNU extensions, so just compile with -std=c++{98,11,14,17,2a}
or -ansi
and it won’t be defined (only __linux__
, __linux
and __gnu_linux__
will be).