2

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?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Mihai
  • 972
  • 2
  • 13
  • 35
  • I can't really tell what your question is. Maybe you could clearly state your question. If you are trying to file a GCC bug report, then try [GCC Bugs](https://gcc.gnu.org/bugs/). – jww Feb 15 '18 at 08:07
  • 1
    I don't have much time to analyze but maybe related: https://stackoverflow.com/questions/19210935/why-does-the-c-preprocessor-interpret-the-word-linux-as-the-constant-1 – ymonad Feb 15 '18 at 08:08
  • @ymonad thx, it seems related to that one – Mihai Feb 15 '18 at 08:11
  • Possible duplicate of [Why does the C preprocessor interpret the word "linux" as the constant "1"?](https://stackoverflow.com/questions/19210935/why-does-the-c-preprocessor-interpret-the-word-linux-as-the-constant-1) – phuclv Feb 15 '18 at 10:09

1 Answers1

1

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

Mihai
  • 972
  • 2
  • 13
  • 35
  • It's probably the answer for GCC, but IIRC the character sequence `#include "test-linux/include/include.hpp"` is **not** a string token, but a _header-name_, in particular a _q-char-sequence_. Formally that allows a compiler to accept `#include "C:\test"` without parsing `\t` as a tab character. – MSalters Feb 15 '18 at 15:02