8

I have a header file that I am trying to include from another source file using include pre-processor directory. I have tried to use both quoted form as well as angle-braket form, but neither seem to do the job.

The file name is .>"hello.h and a directory where it is searched by the compiler. I have tried to include it like this:

  • #include <.>"hello.h>
  • #include <.\>"hello.h>
  • #include <.\>\"hello.h>
  • #include ".>"hello.h"
  • #include ".>\"hello.h"

I also tried different C and C++ compilers — clang, gcc, clang++ and g++.

Obviously, none of the above worked or otherwise there would have been no question.

I thought that maybe the name is not legal according to the standard. Unfortunately, I have neither C nor C++ standard specifications on hand. The only authoritative source of information I could find was this MSDN page about #include directive, and GNU C preprocessor documentation, here. GNU's documentation does not say much, MSDN has the following clause, however:

The path-spec is a file name optionally preceded by a directory specification. The file name must name an existing file. The syntax of the path-spec depends on the operating system on which the program is compiled.

I am curious as to what C and C++ standards say about this?

Where do I find those OS-specific rules for C and C++ header file naming requirements? I am particularly interested in OS X, Linux and FreeBSD.

Why escaping < and/or " characters does not work?

How do I include my file?

11
  • 4
    I know its not answering the question, but why not.... rename the file? It is terribly named anyway. Commented Aug 15, 2013 at 17:35
  • 1
    This thread Where do I find the current C or C++ standard documents if you want to find different versions of the standards. Commented Aug 15, 2013 at 17:48
  • 2
    Even if this did work, I would suggest renaming the file. It will be HORRIBLE to work with a file like that on a command line, and it will most likely upset most tools that run through a shell/command prompt interface (such as makefiles). Commented Aug 15, 2013 at 17:49
  • 2
    Doctor, it hurts when I do this. Well, just don't do that! Commented Aug 15, 2013 at 17:50
  • 1
    Interestingly, #include ".>\"hello.h" does work to include a file named .>\"hello.h using Apple clang 4.0 (418.0.60) on OS X. Escaping the quote with a backslash allows the compiler to recognize the string, but the backslash is not removed in forming the file name to open. Commented Aug 15, 2013 at 17:51

4 Answers 4

10

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.

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks. I appreciate you quoting the standard. Any change you have a quote for C++ as well?
@VladLazarenko I am looking up for C++ but I am pretty sure it is similar.
@ShafikYaghmour: It's in C++11 2.9, and the wording is practically the same as C99.
This is great. Now I know that include file names are not only implementation-specific (OS-dependent) but that standard also prohibits having both " and (> or <) at the same time. Thanks!
5

In both C and C++, that's not a valid header name since it contains both > and ".

The syntax for header names allows those delimited by <> to contain "any member of the source character set except new-line and >", and those delimited by "" to contain "any member of the source character set except new-line and "". There is no concept of an escape sequence.

5 Comments

Good point. The "..." in an include isn't a string literal, and doesn't follow the usual rules for string literals. On the other hand, I'm pretty sure that escaping is allowed (although maybe not for "), and there are contexts where you can start with a string literal, and end up having it interpreted as a " q-char-sequence ". The standard is anything but clear here.
@JamesKanze: The standard clearly specifies the grammar for a header-name - Shakif's answer reproduces it in full. Escaping, or any other way of changing the definition of q-char or h-char, would be a non-standard extension.
I sort of think your right, if you use a q-char-sequence. Other characters may be escaped (since how the name is interpreted is implementation defined), but not ". But what about the solution I propose with #define NAME ".>\"hello.h", then #include NAME In the #define, it is a "token", and the only type of token it can be is a string literal (where the escape is legal)? I think the standard is very vague about this.
@JamesKanze: The only types of token it can be are a string literal or a header name (albeit an invalid one). Once macro replacement has put it into an include directive, surely it will be treated as a header name?
I wish I knew. Macro expansion is defined in terms of tokens, not text, so it has to be a token before it is replaced. On the other hand, we clearly have two distinct token types here, string literal and q-char-sequence, which can only be distinguished by the context in which they appear. The implementers seem to have opted for accepting a string literal as a q-char-sequence in the third form of the #include, but I'm not sure on what grounds.
2

" and > are not valid characters for a filename in Windows. Your filename should be hello.h, or .\hello.h, or ..\hello.h, but not .>"hello.h.

#include "hello.h"
#include ".\hello.h"
#include "..\hello.h"
#include "c:/temp/hello.h"

Which is why you will not find anything in MSDN about it.

ext3 allows most characters (several have to be escaped when used), but it is HIGHLY recommended that you do not use them when naming your header and source files (if for no other reason than readability). For more information: http://pic.dhe.ibm.com/infocenter/compbg/v121v141/index.jsp?topic=%2Fcom.ibm.xlcpp121.bg.doc%2Flanguage_ref%2Fc99preprocessor.html

4 Comments

This answers the question for Windows. I am using OS X, however, and I'd think the file name is legal since it exists and I can open it for reading.
Although the question says "I am particularly interested in OS X, Linux and FreeBSD", which don't share Windows' restrictions.
I would not put a backslash in the name. Even under Windows, #include "../hello.h" is a lot safer.
@Mike, Which is why I added the piece about ext3. The restriction on filenames is mentioned in the standard (someone else already posted that link), but file systems tend to be more strict about filenames than the C++ standard does. He shouldn't be looking at MSDN for information about OSX, FreeBSD, Linux, Unix, etc., as it is virtually useless for that.
0

What is an acceptable filename is implementation defined. I would have expected #include ".>\"hello.h" to work, at least on systems where'>'and'"'` are legal in filenames, but there's no requirement that it work, and there are clearly systems where it won't, because such names are not legal in the system.

You might try forcing the issue:

#define NAME ".>\"hello.h"
#include NAME

But for practical purposes, you should limit your filenames to alphanumerics, underscores, and maybe hyphens (but I'd be leary of those as well). And with only one dot, before the extension. If you go looking for trouble, don't be surprised if you find it.

Which, of course, answers your last question: how do I include the file. You rename it to something sensible.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.