Skip to content
Advertisement

GCC Bug, “linux” string in path replaced with “1” when using “” angle brackets to include a header through a macro

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).

User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement