To dup or not to dup?

Frits van Bommel fvbommel at REMwOVExCAPSs.nl
Mon Feb 26 03:12:20 PST 2007


Jürgen Herz wrote:
> Frits van Bommel wrote:
>> This isn't enforced on Windows. I'm not sure whose fault that is, but I 
>> assume Microsoft :P.
>> Before you think I'm a MS basher, I'd like to mention that IIRC it's not 
>> enforced for C either on Windows: if you initialize char* with a string 
>> literal and try to modify it -- which is illegal in C for the very same 
>> reason -- it won't complain.
> 
> It also isn't enforced for C on Linux (gcc) though it also doesn't
> crash. Anyways, that's C and D (resp. dmd) could do better.

With my Linux gcc it *does* crash:
---
urxae at urxae:~/tmp$ cat test.c
int main() {
         char* str = "test";
         str[0] = 'b';
}
urxae at urxae:~/tmp$ gcc test.c -o test
urxae at urxae:~/tmp$ ./test
Segmentation fault (core dumped)
---

Though it isn't enforced by the compiler.

>> Just because it doesn't crash on your computer doesn't mean it's legal 
>> or that it'll work on every computer (or even on your computer with a 
>> different compiler, for that matter -- though in this case it probably 
>> will if it's because of Windows).
> 
> I understand that it is and why it is illegal. And crashing on Linux I'm
> relieved seeing the "right" consequence of doing illegal things.

Indeed.

> But I'm not convinced of the compiler. In my point of view a language
> and a compiler should catch as many programming errors at the earliest
> point possible, that is at compile time.

Yes, this is usually a good idea.

> What I started with was to find out if there's a const in D. Well, it is
> but ...

There are plans to add a better concept of non-modifiability to D, but 
last I heard Walter and Andrei are still working out the details of how 
it will work.

> To me it looks very inconsequent:
>   char []a = "Test";
>   a[1] = 'x';
> segfaults while
>   const char []a = "Test";
>   a[1] = 'x';
> is caught at compile time with "Error: string literals are immutable".
> Interestingly
>   const char []a = "Test";
>   a[1..2] = "x";
> compiles without warnings though still segfaults.

Current const support is indeed a bit weak.

> Even worse:
>   const char []a = "Test";
>   test(a);
> 
>   void test(char []s)
>   {
>     s[1] = 'x';
>   }
> Not only there doesn't seem no way to declare a function argument const,
> a non-const argument removes const without warnings - and promptly
> segfaults in test.

This is one of the issues that should be addressed by the changes I 
mentioned above.

> On windows the result of that code is very interesting. Since it doesn't
> segfault, one can printf a and s after manipulation. And it's "Txst" in
> test() and "Test" outside.

Yes, it allows it to be modified, which is why it doesn't crash. I'm not 
sure why this is, but my guess is that either PE (the file format of 
Windows executables) doesn't allow you to specify "this part should be 
in read-only memory" or Windows doesn't follow those directions.
I *do* know that ELF (the typical format of Linux executables) allows 
you to specify that and it is enforced when possible (i.e. when possible 
on the processor, which means "if everything on that memory page is 
read-only" on x86 processors)

> BTW
>   const char []a = "Test".dup;
> gives
>   consttest.d(3): Error: cannot evaluate
> _adDupT(&_D12TypeInfo_G4a6__initZ,"Test") at compile time.
> 
> What does in want to tell me?

It wants to tell you that the result of '"Test".dup' cannot be evaluated 
at compile time. In some cases, 'const' really _means_ constant in D, 
the value needs to be available at compile time (or actually at link 
time in many cases).



More information about the Digitalmars-d mailing list