Martin Drozdik
Martin Drozdik

Reputation: 13303

What is the meaning of # in preprocessed C++ code?

I am trying to understand the C++ compilation process in more detail, so I tried to see how the result of C++ pre-processor looks like:

#include <iostream>

int main()
{
    // I am a comment!
    std::cout << "Hi!" << std::endl;
    return 0;
}

I then ran:

g++ -E main.cpp > preprocessed

To run just the preprocessor.

The output is a very long file, since the <iostream> header got expanded along with everything it includes. However, the end of the file looks like this:

...
namespace std __attribute__ ((__visibility__ ("default")))
{

# 60 "/usr/include/c++/4.9/iostream" 3
  extern istream cin;
  extern ostream cout;
  extern ostream cerr;
  extern ostream clog;


  extern wistream wcin;
  extern wostream wcout;
  extern wostream wcerr;
  extern wostream wclog;




  static ios_base::Init __ioinit;


}
# 2 "main.cpp" 2

int main()
{

    std::cout << "Hi!" << std::endl;
    return 0;
}

Expectedly, the comment disappeared, but the preprocessor added some information on lines starting with #.

Are lines beginning with # legal C++? I thought that the sole purpose of # is to designate preprocessor directives. I thought that # is some esoteric way to designate a comment, but this code:

#include <iostream>

int main()
{
    # I am something that follows the hash symbol.
    std::cout << "Hi!" << std::endl;
    return 0;
}

Does not compile.


EDIT:

Apparently # symbols are ok outside the function scope:

g++ -E main.cpp > preprocessed.cpp
g++ preprocessed.cpp -o preprocessed

produces the same executable.

Upvotes: 2

Views: 347

Answers (1)

abligh
abligh

Reputation: 25119

The preprocessed C++ code contains lines starting with a # to convey original line number and function call information to the compiler, so it can:

  • produce error information at the appropriate line
  • produce debug information that links with the line numbers

These are called line markers.

A # in this context is not legal C++ code because it signifies a preprocessor directive. But as the file has already been preprocessed, we know it can't mean that, so it is reused in the preprocessed output file for the purpose set out above.

You can get rid of these by using the -P option. From the man page:

-P Inhibit generation of linemarkers in the output from the preprocessor. This might be useful when running the preprocessor on something that is not C (sic) code, and will be sent to a program which might be confused by the linemarkers.

Note that whilst the manual page refers to C code rather than C++ code (because the manual page is the same for g++ and gcc in this respect), the same consideration applies.

Upvotes: 3

Related Questions