Jump to page: 1 2
Thread overview
Ouch: return values as lvalue
Jan 30, 2007
Lionello Lunesu
Jan 30, 2007
Lionello Lunesu
Jan 31, 2007
Joel C. Salomon
Jan 31, 2007
Joel C. Salomon
Jan 31, 2007
Hasan Aljudy
Jan 31, 2007
Lionello Lunesu
Jan 31, 2007
Walter Bright
Jan 31, 2007
Lionello Lunesu
Other Ouchs (was: Ouch: return values as lvalue)
Jan 30, 2007
Oth Erou
Jan 31, 2007
Lionello Lunesu
Jan 31, 2007
Oth Erou
January 30, 2007
Consider this home-made const:

struct Task {
  char[] ID;
}
private Task _CurrentTask; //mutable
public Task CurrentTask() { return _CurrentTask; } //const

public void StopTask() {
  CurrentTask.ID = null;
}

Notice the bug? That last line should read "_CurrentTask.ID = null;"

Isn't there something the compiler can do to help me catch these bugs?

L.
January 30, 2007
Lionello Lunesu wrote:
> Consider this home-made const:
> 
> struct Task {
>   char[] ID;
> }
> private Task _CurrentTask; //mutable
> public Task CurrentTask() { return _CurrentTask; } //const
> 
> public void StopTask() {
>   CurrentTask.ID = null;
> }
> 
> Notice the bug? That last line should read "_CurrentTask.ID = null;"
> 
> Isn't there something the compiler can do to help me catch these bugs?

const will take care of it. The code above fetches a member of an rvalue, which is an lvalue.

Andrei
January 30, 2007
"Andrei Alexandrescu (See Website For Email)" <SeeWebsiteForEmail@erdani.org> wrote in message news:45BF7C8B.3080506@erdani.org...
> Lionello Lunesu wrote:
>> Consider this home-made const:
>>
>> struct Task {
>>   char[] ID;
>> }
>> private Task _CurrentTask; //mutable
>> public Task CurrentTask() { return _CurrentTask; } //const
>>
>> public void StopTask() {
>>   CurrentTask.ID = null;
>> }
>>
>> Notice the bug? That last line should read "_CurrentTask.ID = null;"
>>
>> Isn't there something the compiler can do to help me catch these bugs?
>
> const will take care of it. The code above fetches a member of an rvalue, which is an lvalue.

Yeah, I know, but it's odd: it's setting a member in a struct that's about to be deleted. It's like writing "{ int id=4; }". Wouldn't it be possible for the compiler to warn about "code without side-effect" or something?

L.


January 30, 2007
Lionello Lunesu wrote:
> "Andrei Alexandrescu (See Website For Email)" <SeeWebsiteForEmail@erdani.org> wrote in message news:45BF7C8B.3080506@erdani.org...
>> Lionello Lunesu wrote:
>>> Consider this home-made const:
>>>
>>> struct Task {
>>>   char[] ID;
>>> }
>>> private Task _CurrentTask; //mutable
>>> public Task CurrentTask() { return _CurrentTask; } //const
>>>
>>> public void StopTask() {
>>>   CurrentTask.ID = null;
>>> }
>>>
>>> Notice the bug? That last line should read "_CurrentTask.ID = null;"
>>>
>>> Isn't there something the compiler can do to help me catch these bugs?
>> const will take care of it. The code above fetches a member of an rvalue, which is an lvalue.
> 
> Yeah, I know, but it's odd: it's setting a member in a struct that's about to be deleted. It's like writing "{ int id=4; }". Wouldn't it be possible for the compiler to warn about "code without side-effect" or something?

Probably it could, but sometimes the object will be used:

foo(bar().baz += 1);

But that can be detected, too. But in generic code you can't rely on one specific expectation. And Walter hates warnings :o).


Andrei
January 30, 2007
Lionello Lunesu Wrote:

> Notice the bug?
void main(){
    real res = 0.01;
    while(res < 0,1)
    {
        if (res >= 0.1) printf("shooting over: %f\n", res),
        printf("Increasing.\n");
        res*=1+1e-10;
    }
}
January 31, 2007
Lionello Lunesu wrote:
> "Andrei Alexandrescu (See Website For Email)" <SeeWebsiteForEmail@erdani.org> wrote in message news:45BF7C8B.3080506@erdani.org...
>> Lionello Lunesu wrote:
>>> Consider this home-made const:
>>>
>>> struct Task {
>>>   char[] ID;
>>> }
>>> private Task _CurrentTask; //mutable
>>> public Task CurrentTask() { return _CurrentTask; } //const
>>>
>>> public void StopTask() {
>>>   CurrentTask.ID = null;
>>> }
>>>
>>> Notice the bug? That last line should read "_CurrentTask.ID = null;"
>>>
>>> Isn't there something the compiler can do to help me catch these bugs?
>> const will take care of it. The code above fetches a member of an rvalue, which is an lvalue.
> 
> Yeah, I know, but it's odd: it's setting a member in a struct that's about to be deleted. It's like writing "{ int id=4; }". Wouldn't it be possible for the compiler to warn about "code without side-effect" or something?

It's a long discussion. I agree that non-templated code without effect should issue a compile-time error (not warning) _____as long as under no change of type definitions etc., the code could make sense_____.

Consider:

struct RealLock { ... }
struct DummyLock { ... }
alias DummyLock Lock;

{
  Lock lock;
  ...
}

DummyLock doesn't do anything. The idea is that the user would replace the alias with RealLock in a multithreaded application.

The compiler shouldn't issue an error, even though the code appears to do nothing interesting.


Andrei
January 31, 2007
Andrei Alexandrescu (See Website For Email) wrote:
> It's a long discussion. I agree that non-templated code without effect should issue a compile-time error (not warning) _____as long as under no change of type definitions etc., the code could make sense_____.

while(func() == 0)
	;

— or do you only mean that extremely short-lived (effect-less) /assignments/ should be errors?

--Joel
January 31, 2007
Joel C. Salomon wrote:
> Andrei Alexandrescu (See Website For Email) wrote:
>> It's a long discussion. I agree that non-templated code without effect should issue a compile-time error (not warning) _____as long as under no change of type definitions etc., the code could make sense_____.
> 
> while(func() == 0)
>     ;
> 
> — or do you only mean that extremely short-lived (effect-less) /assignments/ should be errors?

Code in general. Consider:

1 + 1 == 2;

The code above isn't an error but it also doesn't do anything. It should be flagged as an error.

The empty statement in your example is not "code" the way I meant it above.


Andrei
January 31, 2007
Andrei Alexandrescu (See Website For Email) wrote:
> Joel C. Salomon wrote:
>> Andrei Alexandrescu (See Website For Email) wrote:
>>> It's a long discussion. I agree that non-templated code without effect should issue a compile-time error (not warning) _____as long as under no change of type definitions etc., the code could make sense_____.
>>
>> while(func() == 0)
>>     ;
>>
>> — or do you only mean that extremely short-lived (effect-less) /assignments/ should be errors?
> 
> Code in general. Consider:
> 
> 1 + 1 == 2;
> 
> The code above isn't an error but it also doesn't do anything. It should be flagged as an error.
> 
> The empty statement in your example is not "code" the way I meant it above.

And the lack of a preprocessor means statements like that are unlikely to happen “by accident”.  (I’m afraid I’m still thinking in C.)  Unless this is the sort of thing a code generator might write.

--Joel
January 31, 2007
Joel C. Salomon wrote:
> Andrei Alexandrescu (See Website For Email) wrote:
>> Joel C. Salomon wrote:
>>> Andrei Alexandrescu (See Website For Email) wrote:
>>>> It's a long discussion. I agree that non-templated code without effect should issue a compile-time error (not warning) _____as long as under no change of type definitions etc., the code could make sense_____.
>>>
>>> while(func() == 0)
>>>     ;
>>>
>>> — or do you only mean that extremely short-lived (effect-less) /assignments/ should be errors?
>>
>> Code in general. Consider:
>>
>> 1 + 1 == 2;
>>
>> The code above isn't an error but it also doesn't do anything. It should be flagged as an error.
>>
>> The empty statement in your example is not "code" the way I meant it above.
> 
> And the lack of a preprocessor means statements like that are unlikely to happen “by accident”.  (I’m afraid I’m still thinking in C.)  Unless this is the sort of thing a code generator might write.

Which is exactly what templates do. But, as I show in another post, all you really need is an alias.

Andrei
« First   ‹ Prev
1 2