Topic: Is *(int*)0 an lvalue?


Author: Christopher Eltschka <celtschk@web.de>
Date: Thu, 8 Nov 2001 16:14:30 GMT
Raw View
Francis Glassborow <francis.glassborow@ntlworld.com> writes:

> In article <9s0qrc$t89$1@glue.ucr.edu>, thp@cs.ucr.edu writes
> >Suppose that foo is define:  int foo() { int x; cin >> x; return x; }.
> >
> >Now consider the following two programs:
> >
> >    int main () { if ( !foo() ) *(int*)0 = 1; }
>
> If the compiler compiles that as if it had been:
>
> int main() { foo(); }
>
> I think it would be fully conforming because it would not be possible to
> tell from within the program that that is what the compiler had done.
> Hence I stick with my assertion.

Well, of course the compiler may do this, because it only affects
program runs where the undefined behaviour is invoked. That's an
extreme application of the as-if rule.

The question is, may the compiler *reject* to compile it, based on the
fact that dereferencing a null pointer is undefined behaviour.

The original question was, if the compiler may reject

if (0) *(int*)0 = 1;

AFAIK no one has questioned that the compiler may just optimize it
away.


BTW, you can make the application of the as-if-rule even more extreme,
by compiling

#include<iostream>
#include<iterator>

int main()
{
  int const count = *std::istream_iterator<int>(std::cin);

  double xy;

  // do a lot of calculations

  std::cout << xy/count;
}

into

#include<iostream>
#include<iterator>

int main()
{
  int const count = *std::istream_iterator<int>(std::cin);

  if (!count)
  {
    std::cerr << "Undefined behaviour detected!\n"
                 "About to reformat your hard disk...\n"
                 "Press enter to continue."
    char c;
    std::cin >> c;
    std::cerr << "Ok, just kidding :-)"
    return 1;
  }

  double xy;

  // do a lot of calculations

  std::cout << xy/count;
}

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Balog Pal" <pasa@lib.hu>
Date: Sat, 10 Nov 2001 22:10:06 GMT
Raw View
<thp@cs.ucr.edu> wrote in message news:9s5por$if0$2@glue.ucr.edu...
> Francis Glassborow <francis.glassborow@ntlworld.com> wrote:

> : Actually I am raising the issue that in a world of speculative execution
> : some of our protection now relies on the adequacy of the hardware, or
> : else we must introduce pessimisations by switching off speculative
> : execution for such statements.

Speculative execution does not mean anarchy. Any result on the non-taken branches, including exceptions must be discarded by the processor. From the outside you can't determine if the processor does any speculative prediction stuff or not, except a possible difference in speed.

So that is a non-issue.

Paul

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: thp@cs.ucr.edu
Date: Sat, 10 Nov 2001 23:36:28 GMT
Raw View
Francis Glassborow <francis.glassborow@ntlworld.com> wrote:
: In article <9rtllv$vn7os$1@ID-49767.news.dfncis.de>, Anthony Williams
: <anthwil@nortelnetworks.com> writes
:>unsigned j=sizeof(*((int*)0));
:>
:>The argument to sizeof is never evaluated, it just has its type determined.
:>If *(int*)0 gives undefined behaviour just by its existence, we have a
:>problem. If it must be evaluated, then we're OK.

: I think for something to (mis)behave it must do something other than
: just exist.

AFIK, a well-formed program can invoke undefined behavior only via
what it does or attempts to do.  There is, however, one kind of
ill-formed program that requires no diagnostic, namely those that
violate the one-definition rule.  Per 1.4/2:

  If a program contains a violation of a rule for which no diagnostic
  is required, this International Standard places no requirement on
  implemetations with respect to that program.

Tom Payne

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: thp@cs.ucr.edu
Date: Sat, 3 Nov 2001 00:54:03 GMT
Raw View
Francis Glassborow <francis.glassborow@ntlworld.com> wrote:
: In article <9rt6kj$off$2@glue.ucr.edu>, thp@cs.ucr.edu writes
[...]
:>I'm also suggesting that it might be important to keep those two
:>notions distinct, by offering an expression that is IMHO legal
:>in the first sense (i.e., it is a well-formed expression) but
:>illegal in the second sense.

: But I am not sure that you achieved that. A program that contains
: undefined behaviour is ill-formed.

In general, it is impossible to tell statically whether or not a
at run-time a program will commit the sin of doing something that
invoke undefined behavior.  In the case at hand:

    int main() {
      if ( 0 ) *(int*)0 = 3;
    }

it is in fact possible to statically determine that no such sin will
be committed.  So in what sense does this program contain undefined
behavior any more than say the following program:

    int main() {
      int i;
      cin >> i;
      cout << 1/i;
    }

which may invoke undefined behavior if the user enters zero?

:>: I'll agree that undefined behavior is probably reasonably safe if
:>: you can be certain that the flow of execution never gets there.
:>: But if it's dead code, why does it matter if it's an lvalue or not?
:>
:>Are conforming implementations required/allowed to reject that above
:>program?  Either it is ill formed or it isn't.

: Undefined behaviour is behaviour that is outside any requirements of the
: Standard and so there is no requirement for nor prohibition of a
: diagnostic. I do not believe that there is any clear division between
: compile time and runtime behaviour.

Of course, advice in the form a warning is always permitted.  But,
IMHO, a conforming implementation is not allowed to issue a diagnostic
and/or reject the program in question.  AFIK, that program strictly
conforms and has behavior that is well-defined under the Standard.

There is no prohibition on programs containing fragments that would
yield undefined behavior if executed under circumstances that can
never occur in the program.  For undefined behavior to be invoked, the
program must actually commit a sin that invokes.  No sin, no guilt.

Tom Payne


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Sat, 3 Nov 2001 01:49:21 GMT
Raw View
In article <slrn9u5h3v.sb7.qrczak@qrnik.zagroda>, Marcin 'Qrczak'
Kowalczyk <qrczak@knm.org.pl> writes
>Fri,  2 Nov 2001 15:42:31 GMT, Francis Glassborow <francis.glassborow@ntlworld.c
>om> pisze:
>
>> With modern cpu's there is something called speculative processing and
>> branch prediction. It is therefore possible that code that is not needed
>> because it is on a branch that is not actually followed still gets
>> evaluated.
>
>Are you saying that here:
>
>    int f (int *p)
>    {
>        return p ? *p : 0;
>    }
>
>a compiler would be correct in letting *p be evaluated even if p is
>a null pointer (assuming that dereferencing a null pointer has bad
>consequences on the given platform)?
>
>If not, then the same reasoning applies to if (0) *(int *)0;

Actually I am raising the issue that in a world of speculative execution
some of our protection now relies on the adequacy of the hardware, or
else we must introduce pessimisations by switching off speculative
execution for such statements.

Francis Glassborow
I offer my sympathy and prayers to all those who are suffering
as a result of the events of September 11 2001.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Sat, 3 Nov 2001 12:34:57 GMT
Raw View
In article <9rul8f$88n$1@glue.ucr.edu>, thp@cs.ucr.edu writes
>There is no prohibition on programs containing fragments that would
>yield undefined behavior if executed under circumstances that can
>never occur in the program.  For undefined behavior to be invoked, the
>program must actually commit a sin that invokes.  No sin, no guilt.

That is an assertion, based on belief, I am not entirely convinced that
your belief is well founded. You seem to be claiming that a compiler
must accept:

if(foo()) *(int *)0 = 1;

even though it can only determine that either the line is a waste of
space or it generates undefined behaviour depending on the value of
foo().  I maintain that is unreasonable.




Francis Glassborow
I offer my sympathy and prayers to all those who are suffering
as a result of the events of September 11 2001.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: thp@cs.ucr.edu
Date: Sat, 3 Nov 2001 21:40:57 GMT
Raw View
Francis Glassborow <francis.glassborow@ntlworld.com> wrote:
: In article <9rul8f$88n$1@glue.ucr.edu>, thp@cs.ucr.edu writes
:>There is no prohibition on programs containing fragments that would
:>yield undefined behavior if executed under circumstances that can
:>never occur in the program.  For undefined behavior to be invoked, the
:>program must actually commit a sin that invokes.  No sin, no guilt.

: That is an assertion, based on belief, I am not entirely convinced that
: your belief is well founded. You seem to be claiming that a compiler
: must accept:

: if(foo()) *(int *)0 = 1;

: even though it can only determine that either the line is a waste of
: space or it generates undefined behaviour depending on the value of
: foo().  I maintain that is unreasonable.

Wasting space is not a syntax error, nor is it a violation of a
semantic constraint.  Conforming implementations are not (and should
not be) allowed to reject programs for wasting space.

Suppose that foo is define:  int foo() { int x; cin >> x; return x; }.

Now consider the following two programs:

    int main () { if ( !foo() ) *(int*)0 = 1; }

and

    int main () { 1/foo(); }.

Each of them invokes undefined behavior if the user enters zero and
wastes of space in other cases.  Do you see any difference between
them with regard to whether they (should) conform?

AFIK, only when the occurrence of undefined behavior becomes provably
inevitable is the conforming implementation relieved of its burden of
generating defined behavior for the program.  Once that point occurs,
however, the contract is broken and the conforming implementation has
no obligation (past, present or future) with regard to this particlar
run of this program.

Tom Payne

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: news_comp.std.c++_expires-2002-01-01@nmhq.net (Niklas Matthies)
Date: Sun, 4 Nov 2001 13:55:50 GMT
Raw View
On Sat,  3 Nov 2001 12:34:57 GMT, Francis Glassborow <francis.glassborow@ntlworld.com> wrote:
>  In article <9rul8f$88n$1@glue.ucr.edu>, thp@cs.ucr.edu writes
> >There is no prohibition on programs containing fragments that would
> >yield undefined behavior if executed under circumstances that can
> >never occur in the program.  For undefined behavior to be invoked, the
> >program must actually commit a sin that invokes.  No sin, no guilt.
>
>  That is an assertion, based on belief, I am not entirely convinced that
>  your belief is well founded. You seem to be claiming that a compiler
>  must accept:
>
>  if(foo()) *(int *)0 = 1;
>
>  even though it can only determine that either the line is a waste of
>  space or it generates undefined behaviour depending on the value of
>  foo().  I maintain that is unreasonable.

How about:

  if (implementation_allows_the_following_as_an_extension()) *(int *)0 = 1;

Seems quite reasonable to me.

-- Niklas Matthies
--
Fighting for peace is like fucking for virginity.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Marcin 'Qrczak' Kowalczyk" <qrczak@knm.org.pl>
Date: Sun, 4 Nov 2001 23:03:40 GMT
Raw View
Sat,  3 Nov 2001 12:34:57 GMT, Francis Glassborow <francis.glassborow@ntlworld.com> pisze:

> You seem to be claiming that a compiler must accept:
>
> if(foo()) *(int *)0 = 1;
>
> even though it can only determine that either the line is a waste
> of space or it generates undefined behaviour depending on the value
> of foo().  I maintain that is unreasonable.

IMHO it would be unreasonable to either
- require such sophisticated analysis from all compilers (after
  formalizing what exactly is a waste of space and what isn't), or
- let different compilers accept different programs, even though these
  programs don't use any constructs which have implementation-dependent
  meaning.

But one of these would be needed to make this work as you want.
Which variant do you choose? I don't like either one.

Sometimes code which looks unreasonably is generated automatically.

For example I would not disallow

    switch ((unsigned)x & 3)
    {
        case 0: return 'a';
        case 1: return 'b';
        case 2: return 'c';
        case 3: return 'd';
        default:
          // Is this case unreasonable? After all it's possible
          // to deduce that it's dead code.
          return 'e';
    };

because there is no rule which is violated. A warning is enough.

Another compiler could have less sophisticated analysis and give a
warning when there is no default, failing to realize that cases above
are exhaustive. How would you satisfy both if they were errors rather
than warnings?

--
 __("<  Marcin Kowalczyk * qrczak@knm.org.pl http://qrczak.ids.net.pl/
 \__/
  ^^
QRCZAK

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Mon, 5 Nov 2001 18:42:39 GMT
Raw View
In article <9s0qrc$t89$1@glue.ucr.edu>, thp@cs.ucr.edu writes
>Suppose that foo is define:  int foo() { int x; cin >> x; return x; }.
>
>Now consider the following two programs:
>
>    int main () { if ( !foo() ) *(int*)0 = 1; }

If the compiler compiles that as if it had been:

int main() { foo(); }

I think it would be fully conforming because it would not be possible to
tell from within the program that that is what the compiler had done.
Hence I stick with my assertion.


Francis Glassborow
I offer my sympathy and prayers to all those who are suffering
as a result of the events of September 11 2001.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: thp@cs.ucr.edu
Date: Mon, 5 Nov 2001 18:43:01 GMT
Raw View
Francis Glassborow <francis.glassborow@ntlworld.com> wrote:
[...]
: Actually I am raising the issue that in a world of speculative execution
: some of our protection now relies on the adequacy of the hardware, or
: else we must introduce pessimisations by switching off speculative
: execution for such statements.

What is the difference between

   if ( 0 ) *(int*)0;  // a deliberately nonsensical construct

and

   if ( p ) foo(*p);   // a very common and useful construct

with regard to the dangers posed under speculative execution?

Tom Payne

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Martin von Loewis <loewis@informatik.hu-berlin.de>
Date: Mon, 5 Nov 2001 18:42:51 GMT
Raw View
Nicola Musatti <objectway@divalsim.it> writes:

> The term "undefined behaviour" refers to a program being executed, so
> it's *always* a runtime property.

No. 1.3.12 even says (in the note)

# permissible undefined behavior ranges from ignoring the situation
# completely with unpredictable results, to behaving during
# translation or program execution in a documented manner
# characteristic of the environment (with or with-out the issuance of
# a diagnostic message), to terminating a translation or execution
# (with the issuance of a diagnostic message).

So a program that uses undefined behaviour may fail to compile. A
typical example is the call to a pure virtual function in a
constructor; some compilers refuse to compile such a program.

Regards,
Martin

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: thp@cs.ucr.edu
Date: Mon, 5 Nov 2001 18:43:06 GMT
Raw View
Francis Glassborow <francis.glassborow@ntlworld.com> wrote:
: In article <3BE2B85B.611B8EFA@divalsim.it>, Nicola Musatti
: <objectway@divalsim.it> writes
:>The term "undefined behaviour" refers to a program being executed, so
:>it's *always* a runtime property. Still, the conditions that lead to
:>undefined behaviour can sometimes be detectable at compile time as in:

: I think the distinction between runtime and compile time is sometimes
: artificial. I do not think compilers are constrained not to evaluate
: things if evaluation is possible.

Speculative execution has to be prepared to deal with the dereferencing
of null pointers, e.g., in the visibly well-formed statement

   if ( p ) *p;

which is equivalent to

   if ( 0 ) *(int*)0

whenever p == 0.

Tom Payne

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Mon, 5 Nov 2001 18:43:07 GMT
Raw View
In article <slrn9u7sr5.qok.qrczak@qrnik.zagroda>, Marcin 'Qrczak'
Kowalczyk <qrczak@knm.org.pl> writes
>> You seem to be claiming that a compiler must accept:
>>
>> if(foo()) *(int *)0 = 1;
>>
>> even though it can only determine that either the line is a waste
>> of space or it generates undefined behaviour depending on the value
>> of foo().  I maintain that is unreasonable.
>
>IMHO it would be unreasonable to either
>- require such sophisticated analysis from all compilers (after
>  formalizing what exactly is a waste of space and what isn't), or
>- let different compilers accept different programs, even though these
>  programs don't use any constructs which have implementation-dependent
>  meaning.
>
>But one of these would be needed to make this work as you want.
>Which variant do you choose? I don't like either one.

I think you are dangerously close to extending undefined behaviour to
requiring a compiler to generate code for it. That leaves a single sane
option, the compiler simply optimises away an expression it detects as
containing undefined behaviour.

Personally I would much prefer a diagnostic, even if one is not
required.

>
>Sometimes code which looks unreasonably is generated automatically.
>
>For example I would not disallow
>
>    switch ((unsigned)x & 3)
>    {
>        case 0: return 'a';
>        case 1: return 'b';
>        case 2: return 'c';
>        case 3: return 'd';
>        default:
>          // Is this case unreasonable? After all it's possible
>          // to deduce that it's dead code.
>          return 'e';
>    };
And a compiler is entirely free to optimise away the default as it is
always free to optimise away dead code.


>
>because there is no rule which is violated. A warning is enough.
>
>Another compiler could have less sophisticated analysis and give a
>warning when there is no default, failing to realize that cases above
>are exhaustive. How would you satisfy both if they were errors rather
>than warnings?

Francis Glassborow
I offer my sympathy and prayers to all those who are suffering
as a result of the events of September 11 2001.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: thp@cs.ucr.edu
Date: Mon, 5 Nov 2001 19:43:18 GMT
Raw View
Martin von Loewis <loewis@informatik.hu-berlin.de> wrote:
: Nicola Musatti <objectway@divalsim.it> writes:

:> The term "undefined behaviour" refers to a program being executed, so
:> it's *always* a runtime property.

: No. 1.3.12 even says (in the note)

: # permissible undefined behavior ranges from ignoring the situation
: # completely with unpredictable results, to behaving during
: # translation or program execution in a documented manner
: # characteristic of the environment (with or with-out the issuance of
: # a diagnostic message), to terminating a translation or execution
: # (with the issuance of a diagnostic message).

: So a program that uses undefined behaviour may fail to compile. A
: typical example is the call to a pure virtual function in a
: constructor; some compilers refuse to compile such a program.

The contract between the program and the conforming implementation is
dissolved when and only when undefined behavior becomes inevitable.
When that contract is dissolved it is no longer applicable, even to
the behavior that occurred prior to the dissolution.

Tom Payne



















---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: thp@cs.ucr.edu
Date: Mon, 5 Nov 2001 15:49:35 CST
Raw View
Francis Glassborow <francis.glassborow@ntlworld.com> wrote:
: In article <slrn9u7sr5.qok.qrczak@qrnik.zagroda>, Marcin 'Qrczak'
: Kowalczyk <qrczak@knm.org.pl> writes
:>> You seem to be claiming that a compiler must accept:
:>>
:>> if(foo()) *(int *)0 = 1;
:>>
:>> even though it can only determine that either the line is a waste
:>> of space or it generates undefined behaviour depending on the value
:>> of foo().  I maintain that is unreasonable.
:>
:>IMHO it would be unreasonable to either
:>- require such sophisticated analysis from all compilers (after
:>  formalizing what exactly is a waste of space and what isn't), or
:>- let different compilers accept different programs, even though these
:>  programs don't use any constructs which have implementation-dependent
:>  meaning.
:>
:>But one of these would be needed to make this work as you want.
:>Which variant do you choose? I don't like either one.

: I think you are dangerously close to extending undefined behaviour to
: requiring a compiler to generate code for it. That leaves a single sane
: option, the compiler simply optimises away an expression it detects as
: containing undefined behaviour.

When p is null the well-formed and conforming statement

    if ( p ) foo( *p );

runs into the same issues of undefined behavior as does

    if ( 0 ) *(int*)0;

But this statement cannot be optimized away unless the compiler can
determined that p is always null.  In general, that determination
cannot be made at compile time due both to possible randomness of
input and to issues related to the halting problem.

Tom Payne
































---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Martin von Loewis <loewis@informatik.hu-berlin.de>
Date: Mon, 5 Nov 2001 15:49:36 CST
Raw View
thp@cs.ucr.edu writes:

> : So a program that uses undefined behaviour may fail to compile. A
> : typical example is the call to a pure virtual function in a
> : constructor; some compilers refuse to compile such a program.
>
> The contract between the program and the conforming implementation is
> dissolved when and only when undefined behavior becomes inevitable.
> When that contract is dissolved it is no longer applicable, even to
> the behavior that occurred prior to the dissolution.

Can you kindly refer me to the formal language in the standard that
supports your understanding? Are you saying a compiler is wrong which
rejects a call to a pure virtual function, on the grounds that the
constructor containing the call may never be executed?

Regards,
Martin

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: thp@cs.ucr.edu
Date: Tue, 6 Nov 2001 00:11:32 GMT
Raw View
Martin von Loewis <loewis@informatik.hu-berlin.de> wrote:
: thp@cs.ucr.edu writes:

:> : So a program that uses undefined behaviour may fail to compile. A
:> : typical example is the call to a pure virtual function in a
:> : constructor; some compilers refuse to compile such a program.
:>
:> The contract between the program and the conforming implementation is
:> dissolved when and only when undefined behavior becomes inevitable.
:> When that contract is dissolved it is no longer applicable, even to
:> the behavior that occurred prior to the dissolution.

: Can you kindly refer me to the formal language in the standard that
: supports your understanding? Are you saying a compiler is wrong which
: rejects a call to a pure virtual function, on the grounds that the
: constructor containing the call may never be executed?

Yes.  If a conforming implementation can reject any program that
contains a never-taken path to undefined behavior, then most
programs are rejectable, e.g., any program that a line of the form:

    if ( p ) ... *p ...;

or any program that calls malloc or any program that opens a file.
IMHO, that's not what the designers of the language had in mind.

Tom Payne

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: thp@cs.ucr.edu
Date: Tue, 6 Nov 2001 10:04:47 GMT
Raw View
Francis Glassborow <francis.glassborow@ntlworld.com> wrote:
: In article <9s0qrc$t89$1@glue.ucr.edu>, thp@cs.ucr.edu writes
:>Suppose that foo is define:  int foo() { int x; cin >> x; return x; }.
:>
:>Now consider the following two programs:
:>
:>    int main () { if ( !foo() ) *(int*)0 = 1; }

: If the compiler compiles that as if it had been:

: int main() { foo(); }

: I think it would be fully conforming because it would not be possible to
: tell from within the program that that is what the compiler had done.

Since the conformance of a program cannot be changed by how this or
that implmentation evaluates it, I assume that your "it" refers to the
compiler.  If so, we are in full agreement.  ;-)

Tom Payne




















---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Valentin.Bonnard@free.fr (Valentin Bonnard)
Date: Tue, 6 Nov 2001 10:05:34 GMT
Raw View
Martin von Loewis  wrote:
> Nicola Musatti <objectway@divalsim.it> writes:
>
>> The term "undefined behaviour" refers to a program being executed, so
>> it's *always* a runtime property.
>
> No. 1.3.12 even says (in the note)

1.3.12 makes non sens what-so-ever and should simply
be ignored when reading the standard.

  --   VB

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Valentin.Bonnard@free.fr (Valentin Bonnard)
Date: Tue, 6 Nov 2001 18:41:38 GMT
Raw View
thp@cs.ucr.edu wrote:

> that's not what the designers of the language had in mind.

What makes you think that the designerS of the language had
the same thing/something consistent in mind, to be bale to
speak of what they (as a group) had in mind, as opposed to
what each of them had in mind   ?

(That's where a rational is useful: it doesn't tell what a
feature is good for (why a missing feature is useless), but
it tells you what the people who argued such feature wanted
to achieve.)

Note that Steve Clamage and Francis Glassborow disagree with
your, maybe incorrect, exegesis.

I think that is more than enough to raise a DR, and maybe
get a chance to fix the whole 1.3 (or is 1.3.14 a joke [*]   ?).

  --   VB

[*] A good one, IMO.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: thp@cs.ucr.edu
Date: Tue, 6 Nov 2001 18:41:53 GMT
Raw View
Valentin Bonnard <Valentin.Bonnard@free.fr> wrote:
: Martin von Loewis  wrote:
:> Nicola Musatti <objectway@divalsim.it> writes:
:>
:>> The term "undefined behaviour" refers to a program being executed, so
:>> it's *always* a runtime property.
:>
:> No. 1.3.12 even says (in the note)

: 1.3.12 makes non sens what-so-ever and should simply
: be ignored when reading the standard.

In terms of logic, this attempt at defining "permissible undefined
behavior" is the high-point of the standard.  No reader should fail to
miss it.

Tom Payne


















---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "James Kuyper Jr." <kuyper@wizard.net>
Date: Wed, 7 Nov 2001 02:35:01 GMT
Raw View
thp@cs.ucr.edu wrote:
...
> : 1.3.12 makes non sens what-so-ever and should simply
> : be ignored when reading the standard.
>
> In terms of logic, this attempt at defining "permissible undefined
> behavior" is the high-point of the standard.  No reader should fail to
> miss it.

The note in section 1.3.12 contains some examples of permissible
undefined behavior, but that was not an attempt to define "permissible
undefined behavior". There is, quite literally, nothing that doesn't
qualify as permissible undefined behavior. Undefined behavior is
behavior that is not defined, and that's all there is to it. Those
examples were simply meant to emphasis that point.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: thp@cs.ucr.edu
Date: Wed, 7 Nov 2001 16:09:26 GMT
Raw View
Valentin Bonnard <Valentin.Bonnard@free.fr> wrote:
: thp@cs.ucr.edu wrote:

:> that's not what the designers of the language had in mind.

: What makes you think that the designers of the language had=20
: the same thing/something consistent in mind, to be bale to=20
: speak of what they (as a group) had in mind, as opposed to=20
: what each of them had in mind ?


One doesn't need to be psychic to determine that the designers
intended that classical programs, e.g., hello-world, should conform.
There are many such programs that dereference pointers returned by
classical library functions after testing them for nullness.

[...]
: Note that Steve Clamage and Francis Glassborow disagree with=20
: your, maybe incorrect, exegesis.

Hmmmmm.  No posting by Steve Clamage in this thread has yet reached my
news server. =20

Francis seems to agree that undefined behavior is a run-time
occurrence, but seems to think that it includes behavior that occurs
only speculatively.  My previous post notes that prohibiting code
whose speculative execution might lead to undefined behavior prohibits
dereferencing the pointers returned by classical library functions
like fopen() and malloc().

: I think that is more than enough to raise a DR,=20

I expected/hoped that this thread would lead to a DR.=09

: and maybe get a chance to fix the whole 1.3 (or is 1.3.14 a joke [*]=A0=
?).

:   --=A0VB

: [*] A good one, IMO.

Agreed.  I'm particularly fond of the term "permissible undefined
behavior".

Tom Payne





















---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: thp@cs.ucr.edu
Date: Mon, 29 Oct 2001 16:13:47 GMT
Raw View
My question is whether *(int*)0 is an lvalue?  But that seems to
really be two possible questions:

  (1) Is the expression '*(int*)0' an lvalue?

  (2) Is the value of the expression '*(int*)0' an lvalue?

So, I have a metaquestion: Are both (1) and (2) well posed, i.e., does
it make sense to refer to an expression as an "lvalue" and to refer to
its value as an "lvalue"?

If so, I suspect that the answers to (1) and (2) are different, which
brings up anoher question: why on earth is term "lvalue" used in such
a dangerously ambiguous way?

Tom Payne

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Fedor G. Pikus" <fedor_pikus@mentorg.com>
Date: Mon, 29 Oct 2001 21:47:47 GMT
Raw View
thp@cs.ucr.edu wrote:

> My question is whether *(int*)0 is an lvalue?  But that seems to
> really be two possible questions:

You've created a NULL pointer to int and dereferenced it. This is
undefined behaviour, so the results can be anything your implementation
wants it to be. On most Unixes, the entire first page, or at least the
address 0x0, are protected in such a way that any attempt to access
*(int*)0 will cause segmentation fault.


>
>   (1) Is the expression '*(int*)0' an lvalue?
>
>   (2) Is the value of the expression '*(int*)0' an lvalue?
>
> So, I have a metaquestion: Are both (1) and (2) well posed, i.e., does
> it make sense to refer to an expression as an "lvalue" and to refer to
> its value as an "lvalue"?
>
> If so, I suspect that the answers to (1) and (2) are different, which
> brings up anoher question: why on earth is term "lvalue" used in such
> a dangerously ambiguous way?
>
> Tom Payne
>
> ---
> [ comp.std.c++ is moderated.  To submit articles, try just posting with ]
> [ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
> [              --- Please see the FAQ before posting. ---               ]
> [ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
>
>



--
                                   Fedor G. Pikus
http://www.pikus.net/~pikus/

Mentor Graphics Corporation         | Phone: (503) 685-4857
8405 SW Boeckman Road               | FAX:   (503) 685-1239
Wilsonville, Oregon 97070           |

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: thp@cs.ucr.edu
Date: Mon, 29 Oct 2001 23:23:10 GMT
Raw View
Fedor G. Pikus <fedor_pikus@mentorg.com> wrote:
: thp@cs.ucr.edu wrote:

:> My question is whether *(int*)0 is an lvalue?  But that seems to
:> really be two possible questions:

: You've created a NULL pointer to int and dereferenced it. This is
: undefined behaviour, so the results can be anything your implementation
: wants it to be. On most Unixes, the entire first page, or at least the
: address 0x0, are protected in such a way that any attempt to access
: *(int*)0 will cause segmentation fault.

I don't agree that I've dereferenced it.  Consider the following program:

    int main() {
       if ( 0 ) *(int*)0 = 3;
    }

AFIK, that program is well formed and does not invoke undefined behavior.

Tom Payne

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: allan_w@my-dejanews.com (Allan W)
Date: Thu, 1 Nov 2001 19:49:25 CST
Raw View
thp@cs.ucr.edu wrote in message news:<9rknfi$qcu$3@glue.ucr.edu>...
> Fedor G. Pikus <fedor_pikus@mentorg.com> wrote:
> : thp@cs.ucr.edu wrote:
>
> :> My question is whether *(int*)0 is an lvalue?  But that seems to
> :> really be two possible questions:
>
> : You've created a NULL pointer to int and dereferenced it. This is
> : undefined behaviour, so the results can be anything your implementation
> : wants it to be. On most Unixes, the entire first page, or at least the
> : address 0x0, are protected in such a way that any attempt to access
> : *(int*)0 will cause segmentation fault.
>
> I don't agree that I've dereferenced it.  Consider the following program:
>
>     int main() {
>        if ( 0 ) *(int*)0 = 3;
>     }
>
> AFIK, that program is well formed and does not invoke undefined behavior.

You seem to be asking about the behavior of code with undefined
behavior, and then suggesting that it's legal if it's never reached!

I'll agree that undefined behavior is probably reasonably safe if
you can be certain that the flow of execution never gets there.
But if it's dead code, why does it matter if it's an lvalue or not?

Let's put it another way. There's a road somewhere in Europe that has
been closed to all traffic because it's unsafe. There's a 40-year-old
road sign that says "Speed limit 60" -- but it doesn't state the units.
(60 Miles per hour? 60 Kilometers per hour? 60 feet per second?).
Since nobody can legally travel there at all, the precise legal speed
limit has no meaning, does it?

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Marcin 'Qrczak' Kowalczyk" <qrczak@knm.org.pl>
Date: Fri, 2 Nov 2001 08:02:23 GMT
Raw View
Thu,  1 Nov 2001 19:49:25 CST, Allan W <allan_w@my-dejanews.com> pisze:

> I'll agree that undefined behavior is probably reasonably safe if
> you can be certain that the flow of execution never gets there.
> But if it's dead code, why does it matter if it's an lvalue or not?

Because the undefined behavior (which is not present here if C++
is consistent) would be caused by runtime conditions (dereferencing
null pointer), and lvalueness of the expression on the lhs of =
is a compile-time requirement.

No runtime conditions hold when the code is not executed - obviously.
Otherwise you could claim that
    void f (int *p) {(*p)++;}
is undefined behavior because p could be a null pointer, even though
the programmer never calls f with the null pointer as the argument.

If the previous example has undefined behavior then there must be a
different cause than dereferencing the null pointer. Like an explicit
exception that unary * applied to a null pointer constant causes
undefined behavior even if not executed.

OTOH there is no reason to accept programs which contain fragments
which are nonsensical wrt. syntax or types. These are static
properties.

If the standard doesn't distinguish between runtime causes of undefined
behavior and compile-time causes and there are cases when it's not
obvious which is meant, then it should be clarified.

--
 __("<  Marcin Kowalczyk * qrczak@knm.org.pl http://qrczak.ids.net.pl/
 \__/
  ^^
QRCZAK

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: thp@cs.ucr.edu
Date: Fri, 2 Nov 2001 15:41:57 GMT
Raw View
Allan W <allan_w@my-dejanews.com> wrote:
: thp@cs.ucr.edu wrote in message news:<9rknfi$qcu$3@glue.ucr.edu>...
:> Fedor G. Pikus <fedor_pikus@mentorg.com> wrote:
:> : thp@cs.ucr.edu wrote:
:>
:> :> My question is whether *(int*)0 is an lvalue?  But that seems to
:> :> really be two possible questions:
:>
:> : You've created a NULL pointer to int and dereferenced it. This is
:> : undefined behaviour, so the results can be anything your implementation
:> : wants it to be. On most Unixes, the entire first page, or at least the
:> : address 0x0, are protected in such a way that any attempt to access
:> : *(int*)0 will cause segmentation fault.
:>
:> I don't agree that I've dereferenced it.  Consider the following program:
:>
:>     int main() {
:>        if ( 0 ) *(int*)0 = 3;
:>     }
:>
:> AFIK, that program is well formed and does not invoke undefined behavior.

: You seem to be asking about the behavior of code with undefined
: behavior, and then suggesting that it's legal if it's never reached!

I'm really asking if there are two distinct notions of illegality:
  - those that require compile time diagnostics and rejection
  - those that lead to "undefined behavior".
I'm also suggesting that it might be important to keep those two
notions distinct, by offering an expression that is IMHO legal
in the first sense (i.e., it is a well-formed expression) but
illegal in the second sense.

: I'll agree that undefined behavior is probably reasonably safe if
: you can be certain that the flow of execution never gets there.
: But if it's dead code, why does it matter if it's an lvalue or not?

Are conforming implementations required/allowed to reject that above
program?  Either it is ill formed or it isn't.

: Let's put it another way. There's a road somewhere in Europe that has
: been closed to all traffic because it's unsafe. There's a 40-year-old
: road sign that says "Speed limit 60" -- but it doesn't state the units.
: (60 Miles per hour? 60 Kilometers per hour? 60 feet per second?).
: Since nobody can legally travel there at all, the precise legal speed
: limit has no meaning, does it?

I can and have driven on the above program in the sense that I've
submitted it to g++ for compilation and execution.

Tom Payne






















---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Anthony Williams" <anthwil@nortelnetworks.com>
Date: Fri, 2 Nov 2001 15:42:24 GMT
Raw View
"Allan W" <allan_w@my-dejanews.com> wrote in message
news:7f2735a5.0111011727.29a7c917@posting.google.com...
> thp@cs.ucr.edu wrote in message news:<9rknfi$qcu$3@glue.ucr.edu>...
> > Fedor G. Pikus <fedor_pikus@mentorg.com> wrote:
> > : thp@cs.ucr.edu wrote:
> >
> > :> My question is whether *(int*)0 is an lvalue?  But that seems to
> > :> really be two possible questions:
> >
> > : You've created a NULL pointer to int and dereferenced it. This is
> > : undefined behaviour, so the results can be anything your
implementation
> > : wants it to be. On most Unixes, the entire first page, or at least the
> > : address 0x0, are protected in such a way that any attempt to access
> > : *(int*)0 will cause segmentation fault.
> >
> > I don't agree that I've dereferenced it.  Consider the following
program:
> >
> >     int main() {
> >        if ( 0 ) *(int*)0 = 3;
> >     }
> >
> > AFIK, that program is well formed and does not invoke undefined
behavior.
>
> You seem to be asking about the behavior of code with undefined
> behavior, and then suggesting that it's legal if it's never reached!
>
> I'll agree that undefined behavior is probably reasonably safe if
> you can be certain that the flow of execution never gets there.
> But if it's dead code, why does it matter if it's an lvalue or not?

unsigned j=sizeof(*((int*)0));

The argument to sizeof is never evaluated, it just has its type determined.
If *(int*)0 gives undefined behaviour just by its existence, we have a
problem. If it must be evaluated, then we're OK.

Anthony
--
Anthony Williams
Software Engineer, Nortel Networks Optical Components Ltd
The opinions expressed in this message are not necessarily those of my
employer



---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Fri, 2 Nov 2001 15:42:31 GMT
Raw View
In article <7f2735a5.0111011727.29a7c917@posting.google.com>, Allan W
<allan_w@my-dejanews.com> writes
>> I don't agree that I've dereferenced it.  Consider the following program:
>>
>>     int main() {
>>        if ( 0 ) *(int*)0 = 3;
>>     }
>>
>> AFIK, that program is well formed and does not invoke undefined behavior.
>
>You seem to be asking about the behavior of code with undefined
>behavior, and then suggesting that it's legal if it's never reached!

However there are two points that need consideration:

*(int *)0 might be evaluated at compile time as part of an optimisation
(is it only legal for a compiler to optimise well-formed code). And yes,
a good optimising  compiler will discard the line entirely:)

With modern cpu's there is something called speculative processing and
branch prediction. It is therefore possible that code that is not needed
because it is on a branch that is not actually followed still gets
evaluated.

With the exact code above you should not have a problem but there are
many 'always false' control expressions that most compilers will not
identify as such where the above two things could be problematic.


Francis Glassborow
I offer my sympathy and prayers to all those who are suffering
as a result of the events of September 11 2001.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Nicola Musatti <objectway@divalsim.it>
Date: Fri, 2 Nov 2001 15:42:41 GMT
Raw View

Marcin 'Qrczak' Kowalczyk wrote:
[...]
> If the standard doesn't distinguish between runtime causes of undefined
> behavior and compile-time causes and there are cases when it's not
> obvious which is meant, then it should be clarified.

The term "undefined behaviour" refers to a program being executed, so
it's *always* a runtime property. Still, the conditions that lead to
undefined behaviour can sometimes be detectable at compile time as in:

int main() {
  int i = *(int *)0;
}

Another thing is a program being "malformed", that is not adherent to
the language syntax. This may again lead to undefined behaviour, because
the standard leaves it to the impelentations to decide under which
conditions to produce an executable.

Cheers,
Nicola Musatti

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: thp@cs.ucr.edu
Date: Fri, 2 Nov 2001 15:42:42 GMT
Raw View
Marcin 'Qrczak' Kowalczyk <qrczak@knm.org.pl> wrote:
[...]
: OTOH there is no reason to accept programs which contain fragments
: which are nonsensical wrt. syntax or types. These are static
: properties.

Compile time rejection of nonsensical fragments is something of a
slippery slope.  We may be able to tell syntactically that '*(int*)0'
is nonsense, but what about '*p()'?  Trying to determine at compile
time, whether p() ever returns a non-null value runs directly into
various problems, e.g.:
  - predicting user input
  - independent compilation
  - the equivalent of the halting problem.

Tom Payne

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Marcin 'Qrczak' Kowalczyk" <qrczak@knm.org.pl>
Date: Fri, 2 Nov 2001 16:31:40 GMT
Raw View
Fri,  2 Nov 2001 15:42:42 GMT, thp@cs.ucr.edu <thp@cs.ucr.edu> pisze:

> Compile time rejection of nonsensical fragments is something of a
> slippery slope.  We may be able to tell syntactically that '*(int*)0'
> is nonsense, but what about '*p()'?  Trying to determine at compile
> time, whether p() ever returns a non-null value runs directly into
> various problems,

That's why it should not be rejected, and thus similarly *(int*)0
(unless we create a special case). Dereferencing null pointers falls
into runtime errors, not compile errors. A compiler may generate
a warning if it happens to detect that a particular dereferenced
pointer will be null.

--
 __("<  Marcin Kowalczyk * qrczak@knm.org.pl http://qrczak.ids.net.pl/
 \__/
  ^^
QRCZAK

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: thp@cs.ucr.edu
Date: Fri, 2 Nov 2001 16:39:35 GMT
Raw View
Francis Glassborow <francis.glassborow@ntlworld.com> wrote:
[...]
: *(int *)0 might be evaluated at compile time as part of an optimisation
: (is it only legal for a compiler to optimise well-formed code). And yes,
: a good optimising  compiler will discard the line entirely:)

AFIK, if a compiler gets itself in trouble by evaluating code that
doesn't get evaluated at run time, then that compiler fails to
conform.

: With modern cpu's there is something called speculative processing and
: branch prediction. It is therefore possible that code that is not needed
: because it is on a branch that is not actually followed still gets
: evaluated.

: With the exact code above you should not have a problem but there are
: many 'always false' control expressions that most compilers will not
: identify as such where the above two things could be problematic.

In fact, given any correct static analyzer, there are some
always-false expressions that this analyzer will not find.  (Such an
expression can be constructed via the same argument as the one used in
the halting problem.)

Tom Payne

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Fri, 2 Nov 2001 16:47:39 GMT
Raw View
In article <9rt6kj$off$2@glue.ucr.edu>, thp@cs.ucr.edu writes
>Allan W <allan_w@my-dejanews.com> wrote:
>: thp@cs.ucr.edu wrote in message news:<9rknfi$qcu$3@glue.ucr.edu>...
>:> Fedor G. Pikus <fedor_pikus@mentorg.com> wrote:
>:> : thp@cs.ucr.edu wrote:
>:>
>:> :> My question is whether *(int*)0 is an lvalue?  But that seems to
>:> :> really be two possible questions:
>:>
>:> : You've created a NULL pointer to int and dereferenced it. This is
>:> : undefined behaviour, so the results can be anything your implementation
>:> : wants it to be. On most Unixes, the entire first page, or at least the
>:> : address 0x0, are protected in such a way that any attempt to access
>:> : *(int*)0 will cause segmentation fault.
>:>
>:> I don't agree that I've dereferenced it.  Consider the following program:
>:>
>:>     int main() {
>:>        if ( 0 ) *(int*)0 = 3;
>:>     }
>:>
>:> AFIK, that program is well formed and does not invoke undefined behavior.
>
>: You seem to be asking about the behavior of code with undefined
>: behavior, and then suggesting that it's legal if it's never reached!
>
>I'm really asking if there are two distinct notions of illegality:

Yes, though we should not apply the term illegality, but the term 'ill-
formed'

>  - those that require compile time diagnostics and rejection

Yes, the standard is quite clear that there are errors that require
diagnostics (all syntactic errors and a few semantic ones)

>  - those that lead to "undefined behavior".

Yes, most semantic errors make no requirement on the compiler.

>I'm also suggesting that it might be important to keep those two
>notions distinct, by offering an expression that is IMHO legal
>in the first sense (i.e., it is a well-formed expression) but
>illegal in the second sense.

But I am not sure that you achieved that. A program that contains
undefined behaviour is ill-formed.

>
>: I'll agree that undefined behavior is probably reasonably safe if
>: you can be certain that the flow of execution never gets there.
>: But if it's dead code, why does it matter if it's an lvalue or not?
>
>Are conforming implementations required/allowed to reject that above
>program?  Either it is ill formed or it isn't.

Undefined behaviour is behaviour that is outside any requirements of the
Standard and so there is no requirement for nor prohibition of a
diagnostic. I do not believe that there is any clear division between
compile time and runtime behaviour.
>

Francis Glassborow
I offer my sympathy and prayers to all those who are suffering
as a result of the events of September 11 2001.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Fri, 2 Nov 2001 16:47:51 GMT
Raw View
In article <9rtllv$vn7os$1@ID-49767.news.dfncis.de>, Anthony Williams
<anthwil@nortelnetworks.com> writes
>unsigned j=sizeof(*((int*)0));
>
>The argument to sizeof is never evaluated, it just has its type determined.
>If *(int*)0 gives undefined behaviour just by its existence, we have a
>problem. If it must be evaluated, then we're OK.

I think for something to (mis)behave it must do something other than
just exist.

Francis Glassborow
I offer my sympathy and prayers to all those who are suffering
as a result of the events of September 11 2001.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Marcin 'Qrczak' Kowalczyk" <qrczak@knm.org.pl>
Date: Sat, 3 Nov 2001 00:52:27 GMT
Raw View
Fri,  2 Nov 2001 15:42:31 GMT, Francis Glassborow <francis.glassborow@ntlworld.com> pisze:

> With modern cpu's there is something called speculative processing and
> branch prediction. It is therefore possible that code that is not needed
> because it is on a branch that is not actually followed still gets
> evaluated.

Are you saying that here:

    int f (int *p)
    {
        return p ? *p : 0;
    }

a compiler would be correct in letting *p be evaluated even if p is
a null pointer (assuming that dereferencing a null pointer has bad
consequences on the given platform)?

If not, then the same reasoning applies to if (0) *(int *)0;

--
 __("<  Marcin Kowalczyk * qrczak@knm.org.pl http://qrczak.ids.net.pl/
 \__/
  ^^
QRCZAK

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Sat, 3 Nov 2001 00:53:15 GMT
Raw View
In article <3BE2B85B.611B8EFA@divalsim.it>, Nicola Musatti
<objectway@divalsim.it> writes
>The term "undefined behaviour" refers to a program being executed, so
>it's *always* a runtime property. Still, the conditions that lead to
>undefined behaviour can sometimes be detectable at compile time as in:

I think the distinction between runtime and compile time is sometimes
artificial. I do not think compilers are constrained not to evaluate
things if evaluation is possible. For example:

#include <iostream>

int main(){
  int i=3, j=4;
  std::cout<< i+j;
}

does not require that the compiler provide any storage for i and j, it
can, I think, generate the same code as would be produced by:

#include <iostream>

int main(){
  std::cout<< 7;
}

And it could even simplify that single executable line as long as
running the program results in 7 being sent to stdin.



Francis Glassborow
I offer my sympathy and prayers to all those who are suffering
as a result of the events of September 11 2001.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]