Is the Backslash Acceptable in C and C++ #Include Directives

Is the backslash acceptable in C and C++ #include directives?

C99 says (§6.4.7/3):

If the characters ', \, ", //, or /* occur in the sequence between the < and > delimiters, the behavior is undefined. Similarly, if the characters ', \, //, or /* occur in the sequence between the " delimiters, the behavior is undefined.

(footnote: Thus, sequences of characters that resemble escape sequences cause undefined behavior.)

C++03 says (§2.8/2):

If either of the characters ’ or \, or either of the character sequences /* or // appears in a q-char- sequence or a h-char-sequence, or the character " appears in a h-char-sequence, the behavior is undefined.

(footnote: Thus, sequences of characters that resemble escape sequences cause undefined behavior.)

C++11 says (§2.9/2):

The appearance of either of the characters ’ or \ or of either of the character sequences /* or // in a q-char-sequence or an h-char-sequence is conditionally supported with implementation-defined semantics, as is the appearance of the character " in an h-char-sequence.

(footnote: Thus, a sequence of characters that resembles an escape sequence might result in an error, be interpreted as the character corresponding to the escape sequence, or have a completely different meaning, depending on the implementation.)

Therefore, although any compiler might choose to support a backslash in a #include path, it is unlikely that any compiler vendor won't support forward slash, and backslashes are likely to trip some implementations up by virtue of forming escape codes. (Edit: apparently MSVC previously required backslash. Perhaps others on DOS-derived platforms were similar. Hmmm… what can I say.)

C++11 seems to loosen the rules, but "conditionally supported" is not meaningfully better than "causes undefined behavior." The change does more to reflect the existence of certain popular compilers than to describe a portable standard.

Of course, nothing in any of these standards says that there is such a thing as paths. There are filesystems out there with no paths at all! However, many libraries assume pathnames, including POSIX and Boost, so it is reasonable to want a portable way to refer to files within subdirectories.

Forward slash or backslash when declaring includes on C++

Which of them is right, if the both are not, why is one of them right and the other one not?

Only the forward slash / is right. Compilers under Windows systems use an extension that can handle both.

C++ cross-platform include dash

According to the accepted answer to a similar question, just always use forward slash (/) for include paths.

This question should also help.

How do I enable backslash support in GCC?

Nothing a little sed can't fix :)

sed -i '/#include/s/\\/\//g' *.c *.h

Can #include directives go somewhere other than the start of a file (like inside a loop)?

Yep, #include directives can go just about anywhere. Even inside functions, or for loops, or anything. The preprocessor that fills that stuff in doesn't know anything about the C (or C++) language, it's totally dumb.

g++ include directory in the headerfile

The problem is, that you are using backslashes \ when you should be using forward slashes /. Backslashes in include paths are undefined behavior before C++11 and implementation defined afterwards (reference).

So change your include to

#include "NetworkIncludes/TCP_Connexion.h"

and you should be good to go.

How to include a file in C and/or C++

I think you are out of luck with that file name from the draft C99 standard section 6.4.7 Header names the grammar is as follows:

header-name:
< h-char-sequence >
" q-char-sequence "
h-char-sequence:
h-char
h-char-sequence h-char
h-char:
any member of the source character set except
the new-line character and >
q-char-sequence:
q-char
q-char-sequence q-char
q-char:
any member of the source character set except
the new-line character and "

You have both a " and > in the file name which excludes you from both the q-char and h-char specification. I don't think you have much choice but to change the file name.

The grammar is the same in the draft C++ standard, section 2.9 Header names.

Using Backslash-Newline outside of a macro in C

"Splices" -- backslash newline sequences -- are removed before the preprocessor processes the program text. At least that's the theory, bearing in mind that the C standard does not actually define a process called the "preprocessor".

What it does define is a procedure for converting the program text into a stream of tokens which can be parsed, and then turning that into an executable. The procedure consists of eight translation phases, and the compiler must produce the same result as would be produced if the phases were executed one at a time, each one taking as input the output of the previous phase. (Most of the inputs and output are streams of tokens, rather than character strings. So the output GCC produces when run with the -E flag doesn't correspond to anything in the standard, allowing GCC to basically produce whatever output it finds convenient. Or that its authors thought you would find convenient.)

The "as if" clause means that a particular compiler can combine phases or execute them in pieces, as long as it doesn't change the result. So you can really only look at the process as the abstract description of an algorithm. Still, it's useful to understand. The full text is found in §5.1.1.2 of the standard.

A highly condensed and commented description of the phases, which is incomplete and somewhat imprecise in its details, in the hopes that it's easier to digest than the language in the standard. But do read it in the original.

  1. Remove trigraphs (which are now deprecated, so don't worry if you don't know what they are) and, if necessary, convert the program text to whatever character encoding the compiler requires.

  2. Remove splices. All backslash-newline sequences are simply removed from the program text, leaving nothing behind. (OK, that's the theory. In practice, most compilers still know the original source line number of every bit of text. But this information is only used for producing diagnostics.)

  3. Split the text into tokens and whitespace sequences, and replace all comments with a single space character.

  4. "Preprocessing directives are executed, macro invocations are expanded, and _Pragma unary operator expressions are executed". This is as close as the standard gets to defining the preprocessor, so it's reasonable to say that the "preprocessor" is the execution of phase 4. #include directives are preprocessor directives, and processing the include directive starts with passing the included file through phases 1-3 before inserting it into the token stream to be further preprocessed.

  5. Replace all the escape sequences in character and string literals with the actual characters (possibly wide characters) which will be used during execution.

  6. Concatenate adjacent string literals.

  7. Remove all whitespace, leaving only tokens. Convert preprocessing tokens into syntactic tokens. Parse the resulting token stream and convert it into a "translation unit". Or, in other words, compile the program into an object file (although that's way more specific than the language in the standard).

  8. Combine all the translation units and necessary library modules into a single executable image. Informally, this is the linking phase and the result is something you can hand to the operating system for execution.

That's what the standard mandates. But real-world compilers do lots of other stuff, like generate more or less readable error messages; rearrange the code in ways that might make it execute faster and/or occupy less space; insert debugging information into the executable; and produce whatever additional analyses and reports the user has requested (none of which are standardised). This, for example, includes the -E and/or -S outputs. The compiler does these things as a favour to you, and they can be helpful in understanding the way your program was compiled. But you shouldn't take them too seriously, since the official result of the compilation process is the actual executable.

Most compilation toolchains can also produce libraries, so it is not the case that all programs are immediately fully processed into executable images. But that's the only outcome which is standardised. Although the standard refers to libraries, particularly the standard library, it does not make any assumptions about how libraries come into existence.

The standard libraries (and headers) don't even have to exist in the filesystem; it's enough that the compiler recognises their names and responds appropriately. Some of the stuff the standard library has to implement cannot be written in portable C, so it is quite possible that the standard library source code, if it exists, is not all in the form of a standard C program. Standard library headers might include constructs which receive special handling by the compiler, and thus cannot be used by other compilers or copied directly into your program.

This might all seem too much in the air, but the intention was to make it possible to have C implementations which run on extremely limited processors, including processors without any external storage at all. (And it is still quite common to target embedded systems which might be missing lots of things you normally take for granted.) And, on the whole, it's served us pretty well over the years.



Related Topics



Leave a reply



Submit