www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Case sensitivity when linking

reply Lewis <musicaljelly gmail.com> writes:
0. Try the following in DMD on Windows (presumably this issue 
doesn't exist on Linux, but can't test myself)
1. Create File1.d and File2.d. Do something trivial in each that 
won't get compiled out.
2. In File2.d, import File1.d, but change the filename case in 
the import statement. For example, write

     import FilE2.d;

3. In File1.d use whatever you imported somewhere, and compile.

When I do this, I get a linker error. If I fix the case in the 
import statement, it compiles. It looks like this is related to 
how the symbol names get mangled, and the names not matching up 
once we get to the link step.

To me, it seems that this should either be:

- A failure during compile instead of link, with a more helpful 
message about the import failing, or
- A successful link that is permissive of filename case

I lean towards the former. Thoughts?
Jan 28
next sibling parent Lewis <musicaljelly gmail.com> writes:
On Sunday, 29 January 2017 at 07:14:52 UTC, Lewis wrote:
 0. Try the following in DMD on Windows (presumably this issue 
 doesn't exist on Linux, but can't test myself)
 1. Create File1.d and File2.d. Do something trivial in each 
 that won't get compiled out.
 2. In File2.d, import File1.d, but change the filename case in 
 the import statement. For example, write

     import FilE2.d;

 3. In File1.d use whatever you imported somewhere, and compile.

 When I do this, I get a linker error. If I fix the case in the 
 import statement, it compiles. It looks like this is related to 
 how the symbol names get mangled, and the names not matching up 
 once we get to the link step.

 To me, it seems that this should either be:

 - A failure during compile instead of link, with a more helpful 
 message about the import failing, or
 - A successful link that is permissive of filename case

 I lean towards the former. Thoughts?
This is where I wish I could edit posts. Here is what the above should look like, with the typos fixed: 0. Try the following in DMD on Windows (presumably this issue doesn't exist on Linux, but can't test myself) 1. Create File1.d and File2.d. Do something trivial in each that won't get compiled out. 2. In File1.d, import File2.d, but change the filename case in the import statement. For example, write import FilE2.d; 3. In File1.d use whatever you imported somewhere, and compile.
Jan 28
prev sibling next sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
https://digitalmars.com/ctg/ctgLinkSwitches.html#ignorecase

But I suggest, for maximal portability, to treat names as case sensitive.
Jan 28
parent reply Lewis <musicaljelly gmail.com> writes:
On Sunday, 29 January 2017 at 07:31:33 UTC, Walter Bright wrote:
 https://digitalmars.com/ctg/ctgLinkSwitches.html#ignorecase

 But I suggest, for maximal portability, to treat names as case 
 sensitive.
Ah, cool. Agreed, my preference is just to keep everything case-sensitive. I wonder though, would it make sense to make differing case in import statements a compiler error? And possibly give it a similar switch to optlink for ignoring case if need be? I hit this error because of a typo in one of my import statements, but the error message I got back from the linker didn't do a good job of pointing out my mistake (as is understandably true for most linker errors). For a simple and easy-to-catch typo, it seems like we could provide a better error message by catching this in the compiler :)
Jan 28
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/28/2017 11:43 PM, Lewis wrote:
 I wonder though, would it make sense to make differing case in import
statements
 a compiler error? And possibly give it a similar switch to optlink for ignoring
 case if need be? I hit this error because of a typo in one of my import
 statements, but the error message I got back from the linker didn't do a good
 job of pointing out my mistake (as is understandably true for most linker
 errors). For a simple and easy-to-catch typo, it seems like we could provide a
 better error message by catching this in the compiler  :)
The best practice recommendation is to use all lower case in import names. This means you won't get any surprises porting to/from Windows file systems. Some people insist on using mixed case import names, and that's their choice. After all, D is a systems programming language. I'd also stay away from using non-ascii characters in import names.
Jan 29
parent reply Lewis <musicaljelly gmail.com> writes:
On Sunday, 29 January 2017 at 08:55:24 UTC, Walter Bright wrote:
 The best practice recommendation is to use all lower case in 
 import names. This means you won't get any surprises porting 
 to/from Windows file systems. Some people insist on using mixed 
 case import names, and that's their choice. After all, D is a 
 systems programming language.

 I'd also stay away from using non-ascii characters in import 
 names.
I agree that's a good general practice. Even so, I'm curious if there are any reasons against the compiler catching an error like this. Seems like it'd only prevent errors.
Jan 29
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/29/2017 5:50 PM, Lewis wrote:
 I agree that's a good general practice. Even so, I'm curious if there are any
 reasons against the compiler catching an error like this. Seems like it'd only
 prevent errors.
Because some people want to use mixed case in their imports. It's not necessarily an error.
Jan 29
parent Lewis <musicaljelly gmail.com> writes:
On Monday, 30 January 2017 at 01:56:16 UTC, Walter Bright wrote:
 On 1/29/2017 5:50 PM, Lewis wrote:
 I agree that's a good general practice. Even so, I'm curious 
 if there are any
 reasons against the compiler catching an error like this. 
 Seems like it'd only
 prevent errors.
Because some people want to use mixed case in their imports. It's not necessarily an error.
To clarify, I agree that the existence of mixed case is not an error (ie having a file called MyFile.d which I import via "import MyFile;" should not be an error). What I'm pondering is the case where I then try to import that same file via "import Myfile;". If the latter is indeed not considered an error, then should optlink perhaps be case-insensitive by default? Otherwise it's almost useless to have the compiler accept this, since the linker will just reject it (unless the linker flag is set, which I suspect the majority of users won't have set). Or am I misunderstanding?
Jan 29
prev sibling parent reply Chris Wright <dhasenan gmail.com> writes:
I'd think the compiler would use the module name you supplied in the 
imported module as the canonical name. Are you not supplying module names? 
Are you changing them between incremental compilation steps? Is the 
compiler ignoring them?

If you don't supply a module name, the compiler could obtain the canonical 
file path with casing:

OSX:
http://stackoverflow.com/questions/370186/how-do-i-find-the-correct-case-
of-a-filename

  FSRef ref;
  FSPathMakeRef(path, &ref, NULL);
  FSRefMakePath(&ref, canonicalPath, MAX_PATH_LENGTH);
  return canonicalPath;

Windows:
http://stackoverflow.com/questions/2113822/python-getting-filename-case-as-
stored-in-windows

  return GetLongPathName(GetShortPathName(path));

Linux:

  (x) => x

Not sure if that would be better.
Jan 29
parent reply Lewis <musicaljelly gmail.com> writes:
On Monday, 30 January 2017 at 03:29:21 UTC, Chris Wright wrote:
 I'd think the compiler would use the module name you supplied 
 in the imported module as the canonical name. Are you not 
 supplying module names? Are you changing them between 
 incremental compilation steps? Is the compiler ignoring them?

 If you don't supply a module name, the compiler could obtain 
 the canonical file path with casing:

 OSX: 
 http://stackoverflow.com/questions/370186/how-do-i-find-the-correct-case-
of-a-filename

   FSRef ref;
   FSPathMakeRef(path, &ref, NULL);
   FSRefMakePath(&ref, canonicalPath, MAX_PATH_LENGTH);
   return canonicalPath;

 Windows: 
 http://stackoverflow.com/questions/2113822/python-getting-filename-case-as-
stored-in-windows

   return GetLongPathName(GetShortPathName(path));

 Linux:

   (x) => x

 Not sure if that would be better.
I haven't been using a module name inside the file itself, I generally just use the filename.
Jan 29
parent reply Chris Wright <dhasenan gmail.com> writes:
On Mon, 30 Jan 2017 03:57:09 +0000, Lewis wrote:
 I haven't been using a module name inside the file itself, I generally
 just use the filename.
Use module names. They take two seconds to type and resolve this problem entirely, along with a couple others (relating to symbolic links, and to non-flat project structures). I could have sworn the compiler yells at you if you don't provide a module name for an imported module, but it doesn't. DIP time?
Jan 29
parent Walter Bright <newshound2 digitalmars.com> writes:
On 1/29/2017 8:46 PM, Chris Wright wrote:
 I could have sworn the compiler yells at you if you don't provide a module
 name for an imported module, but it doesn't. DIP time?
It's intentional. Short programs don't need that stuff. Requiring it now would break an awful lot of code.
Jan 29