
"Version" include wreaks havoc on case-insensitive filesystems - sirn
https://bugs.llvm.org/show_bug.cgi?id=42540
======
kazinator
If include <version> in angle brackets finds some Autoconf VERSION detritus,
it's because the compiler has been wrongly told to look for <...> headers
locally. (Probably by the same Autoconf junk.)

There is a (not so) modern (any more) gcc option -iquote to specify a
directory to search for #include "..." without affecting #include <...>.

In the TXR project I have a "signal.h" local file:

[http://www.kylheku.com/cgit/txr/tree/signal.h](http://www.kylheku.com/cgit/txr/tree/signal.h)

Yet, <signal.h> is also included. Like in this file:

[http://www.kylheku.com/cgit/txr/tree/signal.c](http://www.kylheku.com/cgit/txr/tree/signal.c)

which has both #include <signal.h> and #include "signal.h".

This is fine, if you know what you're doing. #include <signal.h> has no
business finding that local file, and will not do so, unless someone screws
up.

------
lallysingh
Why is the directory containing VERSION in the include path? Isn't that
normally an include/, src/, or similar?

~~~
earenndil
Because config.h, for whatever reason (possibly to make more easily human-
editable), is created in the top-level directory.

~~~
CaliforniaKarl
It's where autoconf, when told to write out a config.h, typically puts the
file.

See
[https://www.gnu.org/software/autoconf/manual/autoconf-2.69/h...](https://www.gnu.org/software/autoconf/manual/autoconf-2.69/html_node/Configuration-
Headers.html#Configuration-Headers) for more info.

~~~
ncmncm
So, fix autoconf, if you can't retire it. It is actionably hazardous to
require that a directory that contains random files be in the include path.
But I'll bet it doesn't; it is probably just the lazy choice.

That said, there is _no_ requirement at all that "#include <version>" must
pick up a file called "version" (of any case). The compiler could prefer a
file called "version.standard-header", if it exists, or "std/version"; or,
things in <> brackets could be looked up on a different list, such as one
designated by "\--isystem" (which does already exist). There doesn't need to
be such a file at all -- the standard just says what names must be found to be
defined after that point in the code. The compiler can Just Know. Or, it can
recognize just Standard header names, and get them somewhere special. Which is
why we don't bother about this in committee. Doing the dumb thing is dumb, no
matter what we say. Do the smart thing, and trouble evaporates.

I always thought it was mad that compilers shipped with standard header files
that had exactly the name as appears in the standard, and that preprocessors
shipped that favor or require such. If you _need_ for the files to have
exactly those names, define a cpp option naming a file with a list of them,
and exactly where each is.

~~~
emn13
Standards evolve. There's value in keeping things simple and consistent to
allow that. So it'd be a cost to have specifically version treated
exceptionally here, and it'd be a cost to have system headers treated very
differently from other headers (because it makes it harder to extend the
system).

So while it makes sense that system headers needn't be files - in principle -
it sounds like a pretty big change too with some downsides as well. All that
just for "version"?

~~~
ncmncm
Not for <version>, or just for <version>. Rather, for being able to designate
header names without worry about what files have been shoveled into random
directories.

It really is on the compiler implementers for not providing a better
accommodation to this very predictable problem.

That said, fixing the autoconf scripts may be the most immediate route to
sanity for the "config.h" / <version> case, eliminating the problem at its
source.

~~~
a1369209993
> for being able to designate header names

In other words, there's no reason why '#include <foo>' should ever be looking
in the translation unit's directory; that's what '#include "foo"' is for.

~~~
ncmncm
I bet autoconf actually says "-I $top_level" or some such.

What's mad is that -I controls where <> names are searched.

~~~
kazinator
I concur.

-I is a traditional option from Unix compilers with a very silly behavior; but for years now we have had something called -iquote in gcc (and clang).

Before -iquote, there was -I- which is deprecated.

------
darkpuma
Case-insensitive filesystems cause so much trouble, one could almost
mistakenly conclude that causing trouble is their raison d'être.

~~~
bendiksolheim
What troubles do they cause? I might have been lucky, but during my ~10 years
on a a mac, I do not remember having had any problems with case sensitivity on
a file system level. I might be a special case though, as I always name my
files in lower case and with hyphens instead of spaces.

Actually, I kinda like not having the possibility of having both "Downloads"
and "downloads" by mistake in my home folder.

~~~
jackewiehose
Seems like you never had the joy to port some windows-software to linux where
the original developers weren't aware of case-sensitive systems. And you never
hat to work with buggy windows-applications that randomly rewrite/rename files
to all upper-case or something like that.

~~~
tom_
If Unix were case-insensitive too, none of this would be an issue.

~~~
darkpuma
Some MacOS installations are case sensitive, others are not. Sometimes you
find software that was written and tested on the case insensitive version that
fails on case-sensitive filesystems.

Case insensitive filesystems made more sense decades ago than they do today.
Case insensitivity is fundamentally a UX feature that has been implemented in
the wrong layer. Rather than the filesystem itself being case insensitive, the
search functionality in GUI interfaces to the filesystem should be case
insensitive. And furthermore, the user should never be typing out the complete
name of any file that already exists, because everything should provide auto-
completions of existing filenames.

