self-confidence of compiler

  • Thread starter valentin tihomirov
  • Start date
J

Jon Skeet [C# MVP]

No, actually I wouldn't expect that to pass. I agree that you don't need
to know the actual input values of a and b to resolve the question, but it
goes beyond what I expect the compiler to do.

<snip>

Out of interest (and not in any way trying to sound snide) do you know
of any languages/compilers which prevent access to possibly-unassigned
variables in this kind of way? I'm pretty sure Java's rules are similar
to C#'s. I don't recall it being part of the C/C++ spec at all,
although I'm much less familiar with those.

I do feel sorry for language designers when it comes to things like
this - they're never going to please everyone :(
 
P

Peter Duniho

Out of interest (and not in any way trying to sound snide) do you know
of any languages/compilers which prevent access to possibly-unassigned
variables in this kind of way? I'm pretty sure Java's rules are similar
to C#'s. I don't recall it being part of the C/C++ spec at all,
although I'm much less familiar with those.

No...honestly I never really paid much attention to the issue until now.
And I don't think you sounded snide...it's a perfectly reasonable question.

I do know that I don't recall my C++ code generating "this variable is
unassigned" errors, but that's probably due to the lack of *any* checking
as opposed to more correct checking.
I do feel sorry for language designers when it comes to things like
this - they're never going to please everyone :(

Well, like I said, my concerns would probably be greatly addressed simply
by rewording the error. It's fair enough to say "this would make things
too complicated, so we don't do it", but I think it's also fair to say
that the compiler has no business making the absolute claim that a
variable's been used without being assigned unless it actually knows that
for sure.

Pete
 
J

Jon Skeet [C# MVP]

Peter Duniho said:
No...honestly I never really paid much attention to the issue until now.
And I don't think you sounded snide...it's a perfectly reasonable question.

Maybe I'm overly aware of how things can be interpreted in a completely
different way to the intended meaning :)
I do know that I don't recall my C++ code generating "this variable is
unassigned" errors, but that's probably due to the lack of *any* checking
as opposed to more correct checking.

I *seem* to remember that gcc had some checking like this, and
Microsoft's C compiler does with /Wall on, but it's not *hugely* smart
- it still complains at:

#include <stdio.h>

int main(void)
{
int x;
int y=1;
if (y==1)
{
x = 5;
}
printf ("%d", x);
}

Interestingly, the warning here talks about a "potentially
uninitialized local variable" - but if you remove the assignment in the
if statement, it turns the error into just "uninitialized local
variable".
Well, like I said, my concerns would probably be greatly addressed simply
by rewording the error. It's fair enough to say "this would make things
too complicated, so we don't do it", but I think it's also fair to say
that the compiler has no business making the absolute claim that a
variable's been used without being assigned unless it actually knows that
for sure.

Agreed. I'd be happy to cast a vote for such an enhancement request :)
 
J

Joel Lucsy

Jon said:
No it doesn't - if either of those exceptions are thrown, the exception
will be bubbled up to the calling method without the "if" being
evaluated at at..

Ah, right. My mistake. Must have been before my morning caffeine drip.
 
T

tjmadden1128

Peter Duniho <[email protected]> wrote:

I *seem* to remember that gcc had some checking like this, and
Microsoft's C compiler does with /Wall on, but it's not *hugely* smart
- it still complains at:

#include <stdio.h>

int main(void)
{
int x;
int y=1;
if (y==1)
{
x = 5;
}
printf ("%d", x);

}

Interestingly, the warning here talks about a "potentially
uninitialized local variable" - but if you remove the assignment in the
if statement, it turns the error into just "uninitialized local
variable".
<snip>
gcc, aCC (HP-UX), and Digital Mars all complain in some fashion about
uninitialized variables if you set the warning level high enough. I'd
have to do some tests as to what the exact messages are. I've had
issues in the dark past with static locals being used without being
initialized and the compiler not catching that.

Tim
 
K

ktrvnbq02

The more complex the rules are, the harder they are to reason about and
understand. They also make it much harder to verify that a compiler is
correct.

I like languages where the rules are reasonably easy to understand,
even if that means that occasionally I have to spell things out a bit
more for the compiler's benefit.

I'm with Jon on this. I really can't recall more than a handful of
times over the last few years where I've needed to "unnecessarily"
initialise a variable just to please the compiler.

I'll happily do that if it means:

* The compiler is more efficient.
* The compiler codebase is smaller, making maintenance/enhancement
easier and reducing test cases.
* The compiler is less prone to bugs since the codebase/feature set is
smaller.
* The language specifications are smaller and less ambiguous, making
it easier for both users of the language and those implementing/
maintaining a compiler for it to understand (this includes Microsoft
and the Mono project)

I do wonder if Microsoft would have been able to make such relatively
rapid progress as they have with technologies such as LINQ -- much of
which is compiler-driven -- if there were lots more corner-cases for
them to deal with in the compiler and language specifications.


Regards,

Matt
 
A

Andre Kaufmann

Peter said:
No...honestly I never really paid much attention to the issue until
now. And I don't think you sounded snide...it's a perfectly reasonable
question.

I do know that I don't recall my C++ code generating "this variable is
unassigned" errors, but that's probably due to the lack of *any*
checking as opposed to more correct checking.

VC++ also has some basic checking. But in the case of the sample of
valentin t. the C++ compiler simply doesn't warn anymore.
That doesn't mean that the C++ is much better in detection, but simply
turns of the warning if it can't detect the usage of uninitialized
variables anymore.

[...]
Pete
 
A

Andre Kaufmann

valentin said:
fDeleted = false;
uint jobId;

foreach (Struct struct in structures) {
if (struct.type == JOB) {
jobId = struct.id;
if (struct.dataType == STATUS)
fDeteted = (struct.data & STATUS_DELETED) != 0;
}

if (fDeleted)
writeln(jobId + " has completed");

Note that the job id is initialized before the 'deleted' flag gets any
chance to set true. So it is not possible to use not initialized jobId.
Nevertheless, compler forces me to do the useless initialization. Do the
designers of 'clever' robots forsee any overcoming for the limitations they
impose?

Why bother about the initialization at all ;-) ?
Performance ? Hardly. In your example jobId can be assigned multiple
times before fDeleted will be set to true.

Simply take the compiler error as a hint, that you can do some
optimizations of your own:

uint count = structures.count;
while (count-- > 0) {
Struct struct = structures[count];
if (struct.type == JOB) {
if (struct.dataType == STATUS)
{
if ((struct.data & STATUS_DELETED) != 0 && first == false)
{
writeln(struct.id + " has completed");
break;
}
}
}

(hope it compiles ;-) )
This may not appropriate in your case and may be that in this case
reverse looping using an indexer may be slower (depends on the size of
the structures list).


Andre
 
V

valentin tihomirov

We're not talking about deeply nested, strangely-arranged loops, if()
Could you give an example?

Most examples which don't work (that I've seen) either involve for
loops or inter-dependency of two variables (if x is true then y is
definitely initialized).


class Undefined {

delegate void Del();
static void initialize(Del del) {
del();
}

public static void Main(string[] args) {

string user;
initialize(delegate() {
user = "x";
});

System.Console.WriteLine(user);
}


}
 
J

Jon Skeet [C# MVP]

valentin tihomirov said:
Most examples which don't work (that I've seen) either involve for
loops or inter-dependency of two variables (if x is true then y is
definitely initialized).


class Undefined {

delegate void Del();
static void initialize(Del del) {
del();
}

public static void Main(string[] args) {

string user;
initialize(delegate() {
user = "x";
});

System.Console.WriteLine(user);
}
}

I wouldn't class that as simple at all. Changing the implementation of
initialize (eg removing the body, or calling del.BeginInvoke() instead)
will change whether or not the variable is assigned a value.

Now, bear in mind the context of the discussion I was having with Peter
- he said there were "relatively simple" examples where the compiler
should be able to cope but doesn't.

I dread to think how complicated the spec would have to be in order to
be able to guarantee the behaviour here.
 
Top