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?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
  • Um are you compiling using `clang file_one.c file_two.c`?... that could just as easily be the issue. Not sure what you are trying to achieve here. – Jacob Pollack Aug 15 '13 at 17:33
  • 4
    I know its not answering the question, but why not.... rename the file? It is terribly named anyway. – eli Aug 15 '13 at 17:35
  • @JacobPollack: I am compiling as `clang++ -Wall -pedantic -I. -std=c++11 -stdlib=libc++ -o hello ./hello.cc` where `hello.cc` is a file where I need to include `.>"hello.h` from. –  Aug 15 '13 at 17:35
  • These links may help you: [Understanding header and source files in C](http://stackoverflow.com/questions/5904530/understanding-header-and-source-files-in-c), [Source file cannot find the header files](http://stackoverflow.com/questions/15744803/source-file-cannot-find-the-header-files). – haccks Aug 15 '13 at 17:37
  • 1
    This thread [Where do I find the current C or C++ standard documents](http://stackoverflow.com/questions/81656/where-do-i-find-the-current-c-or-c-standard-documents?lq=1) if you want to find different versions of the standards. – Shafik Yaghmour Aug 15 '13 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). – Mats Petersson Aug 15 '13 at 17:49
  • 2
    *Doctor, it hurts when I do this. Well, just don't do that!* – David Rodríguez - dribeas Aug 15 '13 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. – Eric Postpischil Aug 15 '13 at 17:51
  • @EricPostpischil: WOW. They must have fixed it, I have tried 4.2 (clang-425.0.28) –  Aug 15 '13 at 17:53
  • @VladLazarenko: Did you try the same thing? The file is named `.>\"hello.h`, not `.>"hello.h`. – Eric Postpischil Aug 15 '13 at 17:54
  • @EricPostpischil: Oh, sorry, I misunderstood you. Yes, if you escape second double-quote, then clang is looking for `.\>\"hello.h` file. To be honest, compilers should probably prohibit those characters in file names and give a better error message. –  Aug 15 '13 at 17:56

4 Answers4

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.

Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
  • Thanks. I appreciate you quoting the standard. Any change you have a quote for C++ as well? –  Aug 15 '13 at 17:39
  • @VladLazarenko I am looking up for C++ but I am pretty sure it is similar. – Shafik Yaghmour Aug 15 '13 at 17:40
  • 1
    @ShafikYaghmour: It's in C++11 2.9, and the wording is practically the same as C99. – Mike Seymour Aug 15 '13 at 17:41
  • 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! –  Aug 15 '13 at 17:46
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.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
  • 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. – James Kanze Aug 15 '13 at 17:43
  • @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. – Mike Seymour Aug 15 '13 at 17:48
  • 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. – James Kanze Aug 15 '13 at 18:01
  • @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? – Mike Seymour Aug 15 '13 at 18:13
  • 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. – James Kanze Aug 15 '13 at 19:20
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

Zac Howland
  • 15,777
  • 1
  • 26
  • 42
  • 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. –  Aug 15 '13 at 17:37
  • Although the question says "I am particularly interested in OS X, Linux and FreeBSD", which don't share Windows' restrictions. – Mike Seymour Aug 15 '13 at 17:38
  • 3
    I would _not_ put a backslash in the name. Even under Windows, `#include "../hello.h"` is a lot safer. – James Kanze Aug 15 '13 at 17:41
  • @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. – Zac Howland Aug 15 '13 at 17:53
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.

James Kanze
  • 150,581
  • 18
  • 184
  • 329