m8pple / arch2-2014-cw1

2014/2015 - EIE2 - Architecture 2, Coursework 1

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Ambiguity regarding custom header files

hamish-milne opened this issue · comments

The instructions mention that:

You can also add your own private header files (generally a good idea), which should be part of the submitted zip file, but they don't need to follow any specific pattern. However, they should be completely located within the src/[your_login] directory or a sub-directory of it.

But also that:

During compilation, the include directories will be set up to have the include directory (containing mips.h) on the include path.

(Also, the markdown for above segment doesn't quite render correctly)

Taken solely and literally, this implies that custom header files will have to be referenced as ../src/[login]/header.h

You neglected angles/quotes in your example, but my understanding is that what you are saying is true of:

#include  <../src/[login]/header.h>

whereby the relative search is done of standard includes and directories on the -I path, but I believe:

#include "../src/[login]/header.h"

will be relative to the file that contains the #include (and thereby not find anything, unless there is someone else with the login 'src' who has a directory called '[your login]' with header.h inside!) - so for your example directory:

#include "header.h"

would give the expected behaviour?

I trust you more than myself when it comes to this though, so I half-suspect I missed some subtlety :p

To be honest, I'm not 100% sure, but I do believe that the search pattern for include directives doesn't include the directory containing the currently parsed file. If it does, that of course makes things much easier.

Technically, according to the C99 spec;

6.4.7.2: The sequences in both forms of header names are mapped in an implementation-defined manner to headers or external source file names as specified in 6.10.2 [1]

So... to be platform-independent, you can't rely on any search path that is not explicitly specified. This is similar in C++ (section 16.2).

However, the GCC manual [2] defines the behaviour for GCC:

#include <file> - This variant is used for system header files. It searches for a file named file in a standard list of system directories.
#include "file" - This variant is used for header files of your own program. It searches for a file named file first in the directory containing the current file, ... and then the same directories used for <file>

So on GCC at least, using #include "header.h" will solve the problem. I can't seem to find anything helpful in the Clang documentation, however.

[1] C99, ISO/IEC 9899
[2] https://gcc.gnu.org/onlinedocs/gcc-4.4.6/cpp/Include-Syntax.html

(For clarity, I think the best resolution to this would be specifying that the src/<login>/ directory would be on the include path).

Oh nice. I can only say anecdotally for clang that it is also the case.

It's amazing how frequently one is playing fast and loose with the rules without having any idea whatsoever.

I had no idea the directory of the currently compiled file was not implicitly part of the
search path either, I'd always imagined the quote form as prefixing the path of
the current file on to the front of the angle form.

I've never come across a compiler that doesn't do that, but it does appear
to be implementation defined, to a surprising extent.

Does this now mean that without risking undefined behaviour, and with the structure:

./
 `--src/
       +--[login]/
       |         +--include/
       |         |         +--1.h
       |         |         `--2.h
       |         `mips_cpu.cpp
       `...

where 1.h wants to include 2.h, that the include must be "include/2.h" rather than "2.h" or "./2.h"?

You can assume I'll pass it as an absolute reference to the pre-processor, so in that
example you'd need include/2.h. From memory, if you use -I include and compiled from
the root of the structure, then the pre-processor expands the path relative to the
working directory at the point of compiler invocation, rather than later on. However,
the chance of aliasing is usually pretty low, so it's possible it always works
for me by chance...