2

Today I read this question Any rules about underscores in filenames in C/C++?, and I found it very interesting that the standard seems to not allow what is usually seen in many libraries (I also do it in my personal library this way):

For example, in opencv we can see this:

// File: opencv/include/opencv2/opencv.hpp

#include "opencv2/opencv_modules.hpp"

But the standard says:

§ 6.10.2 Source file inclusion

Semantics

5 The implementation shall provide unique mappings for sequences consisting of one or more nondigits or digits (6.4.2.1) followed by a period (.) and a single nondigit. The first character shall not be a digit. The implementation may ignore distinctions of alphabetical case and restrict the mapping to eight significant characters before the period.

nondigit means letters (A-Z a-z) and underscore _.

It says absolutely nothing about / which would imply that it is forbidden to use a path, not to mention dots or hyphens in file names.

To test this first, I wrote a simple program with a source file test.c and a header file _1.2-3~a.hh in the same directory tst/:

// File: test.c

#include "./..//tst//./_1.2-3~a.hh"

int main(void)
{
    char    a [10]  = "abcdefghi";
    char    b [5]   = "qwert";

    strncpy(b, a, 5 - 1);
    printf("b: \"%c%c%c%c%c\"\n", b[0], b[1], b[2], b[3], b[4]);
    /* printed: b: "abcdt" */
    b[5 - 1] = '\0';
    printf("b: \"%c%c%c%c%c\"\n", b[0], b[1], b[2], b[3], b[4]);
    /* printed: b: "abcd" */

    return  0;
}

// File: _1.2-3~a.hh

#include <stdio.h>
#include <string.h>

Which I compiled with this options: $ gcc -std=c11 -pedantic-errors test.c -o tst with no complain from the compiler (I have gcc (Debian 8.2.0-8) 8.2.0).

  • Is it really forbidden to use a relative path in an include?
1
  • 1
    It is not forbidden to use /, but the result of doing so is implementation-defined. Almost everything about the sequences between < and > or between " and " in a #include directive is implementation-defined. The standard says that if you use a name such as abcdefgh.h, the implementation is required to handle it as a unique (subject to case-insensitivity and not using a digit in place of a). The implementation may be case-sensitive; it may allow other characters — these details are implementation-defined, which means that the implementation must document its rules. Commented Feb 24, 2019 at 6:21

2 Answers 2

1

Ah; the standard is really talking about the minimum character set of the filesystem supporting the C compiler.

Anything in the "" (or <> with some preprocessing first) is parsed as a string according to normal C rules and passed from there to the OS to do whatever it wants with it.

This leads to compiler errors on Windows when the programmer forgets to type \\ instead of '\' when writing a path into the header files. On modern Windows we can just use '/' and expect it to work but on older Windows or DOS it didn't.

For extra fun, try

#include "/dev/tty"

Really nice one. It wants you to type C code while compiling.

4
  • However, the standard could have specifically talked about it being a minimum, and that other characters could be implementation defined, but it seems to be very strict about it. Commented Feb 24, 2019 at 2:27
  • As I read it, it even says that implementations could restrict it even more but not extend it. Commented Feb 24, 2019 at 2:44
  • @CacahueteFrito: Do you read it so because of "The first character may not be a digit?" Unfortuantely, that's just poor writing on the part of the spec writers. The whole thing is setting the minimum allowed, and "shall not be a digit" modifies the previous as in, there's no requirement for a minimally conforming system to allow the first character of a filename to be a digit.
    – Joshua
    Commented Feb 24, 2019 at 5:18
  • Yes, that "The first character shall not be a digit" seems to be imposing restrictions. It seems to be banning "1.h" directly, although of course all implementations I know would allow it. Commented Feb 24, 2019 at 9:22
0

I'd would say it's not forbidden but not recommanded since it will not compile in some of cases there.

For example:

  • if you clone this directory into your root (so you'd have C:\test\).
  • if you try to run it in a virtual environment online, you may face issues.

Is it really forbidden to use a path in an include?

Not sure what you mean here: relative paths are commonly used, but using absolute path would be foolish.

1
  • Edited. Of course relative path. And for the ../ it was just to not have to create a subdir and have there the include, but of course in a real library it would only contain subdirs, and would never go up. Commented Feb 24, 2019 at 2:10

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.