Topic: 2 questions about Visual C++ vs. standard


Author: Hyman Rosen <hymie@prolifics.com>
Date: 1999/12/13
Raw View
James Kuyper <kuyper@wizard.net> writes:
> Undefined behavior is defined by 1.3.12 as "behavior, such as might
> arise upon use of an erroneous program construct ...". It's not clear to
> me whether "use" requires execution, or merely translation.

It requires execution. See 1.9/5.


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: kanze@gabi-soft.de
Date: 1999/12/14
Raw View
sirwillard@my-deja.com writes:

|>  You are joking, right?  The possibility that any instruction, intended
|>  or not, could cocievably cause hardware to overheat and catch fire is
|>  the basis of an urban legend.

That's not quite true.  I've already had a card catch fire because of an
error in a strap option, many years ago.  Today, most strap options have
been replaced with a configuration register programmed by software.  Do
that on the card I used, and a programming error could very well have
caused the same effect.

I personally consider that this phenomena was do to an error in the
design of the card, but the card's developpers didn't agree with me.
(Luckily, my boss agreed with me, and I encountered no blame for
starting the fire.  Also luckily, I spotted to smoke quick enough so
that the fire could be extinguished with no major damage, except to the
card in question.)

The fact that it actually happened once in my over 25 years of
experience, however, certainly doesn't prove that it is a likely result
of undefined behavior.

--
James Kanze                         mailto:James.Kanze@gabi-soft.de
Conseils en informatique orientie objet/
                  Beratung in objekt orientierter Datenverarbeitung
Ziegelh|ttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: phalpern@newview.org (Pablo Halpern)
Date: 1999/12/14
Raw View
"AllanW" <AllanW@my-deja.com> wrote:

>> Bennett McElwee <bmcelwee@my-deja.com> wrote:
>> >No, because the above is legal C++. Even this code:
>
>Pablo Halpern <phalpern@newview.org> wrote:
>> So was the original post, but the MSVC 5.0 compiler refused to compile
>> it.
>
>How do you know this? Because Mr. Tsoglin said so?

Yes. Because he said so. The question (especially in the standards
newsgroup) was not about whether MSC 5.0 has some option that Mr.
Tsoglin did not know about but whether a conforming compiler is
permitted to reject the code in his post. The answer is no, it must
reject his code. The behavior he observed was non-conforming. That does
not mean that the MSC 5.0 compiler is bad. This is not a thread about
slamming Microsoft and Mr. Tsoglin was not trying to prove his skill at
either writing C++ or using the MS compiler.

---------------------------------------------------------------
Pablo Halpern                              phalpern@newview.org
Check out my new book, The C++ Standard Library from Scratch at
http://www.halpernwightsoftware.com/stdlib-scratch


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: James Kuyper <kuyper@wizard.net>
Date: 1999/12/14
Raw View
kanze@gabi-soft.de wrote:
...
> The fact that it actually happened once in my over 25 years of
> experience, however, certainly doesn't prove that it is a likely result
> of undefined behavior.

No one said it was likely, only that it was possible.


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1999/12/14
Raw View
Paul Scott wrote:
>
> Francis Glassborow wrote:
> >
>
> >So what is required of a compiler faced with:
> >
> >int main (){
> >  if (false) {
> >     const int i = 1/0;
> >     int array[i]
> >  }
> >  return 0;
> >}
> >
>
> Interesting results from g++ (egcs 1.1.2)
>
> g++ tmp.cc:
>
> tmp.cc: In function `int main()':
> tmp.cc:3: warning: division by zero in `1 / 0'

g++ emitted the required diagnostic, but decided it to be a warning.
I'd be really interested in the value of i ;-)

>
> g++ -Wall tmp.cc:
>
> tmp.cc: In function `int main()':
> tmp.cc:3: warning: division by zero in `1 / 0'
> tmp.cc:4: warning: unused variable `int array[(((1 / 0) - 1) + 1)]'

g++ is correct: You didn't use the variable!
(And we've learned something about g++'s value of 1/0:
(((1 / 0) - 1) + 1) is not negative (since otherwise g++
would notr have accepted the array definition).

BTW, if you make g++ conformance tests, never forget the flags
-ansi -pedantic (or even -ansi -pedantic-errors).

[...]


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: jbarfurth@vossnet.de (Joerg Barfurth)
Date: 1999/12/12
Raw View
Christian Bau <christian.bau@isltd.insignia.com> wrote:


> BTW. One of the most interesting examples of undefined behavior I have
> ever seen is this:
>
>    char* p = 1/0;
>
> As 1/0 invokes undefined behavior, a compiler may obviously assume that
> 1/0 is a constant integer expression with some value. If that value is 0,
> then this is legal C/C++. If that value is not zero, then we have a syntax
> error.
> ---

1/0 is not undefined behaviour, it is ill-formed. Constant expressions
are different in this regard. (See clause 5/p.5)

-- J   rg Barfurth


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: James Kuyper <kuyper@wizard.net>
Date: 1999/12/12
Raw View
Roman Belenov wrote:
>
> Hello Christopher,
>
> CE> I thought the undefined behaviour happens only if the path
> CE> is actually taken.
>
> Undefined  behaviour  term  applies  to  compilation  as  well  as  to
> execution  of  the  program; refusal to compile is one of the possible
> options of handling it.

That doesn't quite cover the problem: the question is whether code that
will not be executed can allow undefined behavior. Certainly, if it does
allow undefined behavior, that behavior can include termination of
translation with a diagnostic.

Undefined behavior is defined by 1.3.12 as "behavior, such as might
arise upon use of an erroneous program construct ...". It's not clear to
me whether "use" requires execution, or merely translation. If it does
require execution, terminating the translation would be allowed only if
the use were guaranteed to occur, no matter how the code was linked or
executed. I'm not in favor of this interpretation, and I don't think it
was the one intended - I just think the wording is unclear.

> CE>  So for the function f above, the compiler
> CE> would have to proof that this function is *ever* called with
> CE> a value of x other than 1 or 2, to legally refuse compiling.
>
> Compilation  of the function doesn't depend upon the use of it (BTW it

But undefined behavior does.

> can  be  called  by the code that is not even written by the moment of
> the compilation, so such proof is impossible).

If the function has local linkage, and the address of the function is
never passed outside the translation unit, then all possible calls to
the function must be in the same translation unit. In that case, such
proof would be possible. I don't think it's required, however.


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1999/12/13
Raw View
Roman Belenov wrote:
>
> Hello Christopher,
>
> CE> I thought the undefined behaviour happens only if the path
> CE> is actually taken.
>
> Undefined  behaviour  term  applies  to  compilation  as  well  as  to
> execution  of  the  program; refusal to compile is one of the possible
> options of handling it.
>
> CE>  So for the function f above, the compiler
> CE> would have to proof that this function is *ever* called with
> CE> a value of x other than 1 or 2, to legally refuse compiling.
>
> Compilation  of the function doesn't depend upon the use of it (BTW it
> can  be  called  by the code that is not even written by the moment of
> the compilation, so such proof is impossible).
>
> CE> Assume f is really intended to take a boolean value,
> CE> and only takes int to accomodate an interface that
> CE> cannot be changed. Then f would never be called with
> CE> anything other than 0 and 1, and the behaviour would
> CE> be well defined.
>
> The compiler can't deduce this from the function definition.

So given your definition, the compiler may refuse to compile

int foo(int& a, int& b)
{
  return a++ + b++;
}

since this function _might_ be called with the same
value for a and b.
Do you really think this is the intention?

Oh, and indeed, it may even refuse to compile

int div(int a, int b)
{
  return a/b;
}

since this might be called with b==0.

I strongly believe this is _not_ the intention of undefined
behaviour.

Note that the "div" example is exactly equivalent to

int div2(int a, int b)
{
  if (b != 0)
    return a/b;
}

Both div and div2 have undefined behaviour exactly if b==0,
and the same defined behaviour otherwise. So if the compiler
is allowed to reject div2, it is also allowed to reject div.


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: danil@ultranet.com (Danil)
Date: 1999/12/09
Raw View
> Pablo Halpern <phalpern@newview.org> wrote:
> > So was the original post, but the MSVC 5.0 compiler refused to compile
> > it.

AllanW@my-deja.com says...
> How do you know this? Because Mr. Tsoglin said so?
>
> Meaning no disrespect: It's possible that Mr. Yuri Tsoglin has 25 years
> of experience writing C and C++ compilers and a Ph.D. in computer
> science. But then again he might be an amateur who started learning
> C++ 6 months ago and is facing his first-ever porting problem. From
> the original post, we can't tell. If it's the latter, then his claim that
> MSVC++5.0 *REFUSED* to compile his program might be among
> the simplest of newbie mistakes.

It might be - but given that he not only supplied the code he used, but
also the compiler diagnostic, we should probably give him the benfit of
the doubt, no?

Is it really all that difficult to accept that MSVC 5.0 is non-
conforming?

> It would take me hours to set up MSVC++ 5.0 to test this out, but I
> would be willing to bet that this message IS a warning in that
> compiler.
>
> Anyone like to prove me wrong? Please try it and report what happens.

"Daddy, I've got cider in my ear!"  In DevStudio 5.0....

int f (int x)
{
    switch (x) {
    case 0:
        return 3;
    case 1:
        return 4;
    }
}

--------------Configuration: Switch - Win32 Debug--------------
Compiling...
main.cpp
C:\Test\Switch\main.cpp(10) :
     error C2202: 'f' : not all control paths return a value
Error executing cl.exe.

main.obj - 1 error(s), 0 warning(s)

InfoViewer Topic

Compiler Error C2202
'function' : not all control paths return a value

The specified function can potentially not return a value.

The following is an example of this error:

int func1( int i )
{
   if( i ) return 3;  // error, nothing returned if i = 0
}
int func2( int i )
{
   if( i ) return 3;
   else return 0;     // OK, always returns a value
}
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Darin Adler <darin@bentspoon.com>
Date: 1999/12/09
Raw View
Bennett McElwee <bmcelwee@my-deja.com> wrote:

> // Program 2
> int f() {}
> int main() {return f();}
>
> // Program 3
> int main() {}
>
> Are programs 2 and 3 legal C++? Obviously, the runtime behaviour of
> these programs would be undefined if the compiler produced code for
> them. But if I try to compile them, what should the compiler do?
> Should it issue a diagnostic, or is its behaviour completely
> undefined?

Program 2 is legal C++. As you note above, the behavior of the program when
executed is undefined. "Flowing off the end of a function is equivalent to a
return with no value; this results in undefined behavior in a
value-returning function." [C++ Standard 6.6.3/2]

Program 3 is legal C++ and the behavior of the program is defined because of
a special case for main(). "If control reaches the end of main without
encountering a return statement, the effect is that of executing 'return
0;'." [C++ Standard 3.6.1/5]

    -- Darin
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Krzysztof Stachlewski" <kstc@box43.gnet.pl>
Date: 1999/12/09
Raw View
AllanW <AllanW@my-deja.com> wrote in message
news:82jv9k$kv3$1@oak.prod.itd.earthlink.net...

> Meaning no disrespect: It's possible that Mr. Yuri Tsoglin has 25 years
> of experience writing C and C++ compilers and a Ph.D. in computer
> science. But then again he might be an amateur who started learning
> C++ 6 months ago and is facing his first-ever porting problem. From
> the original post, we can't tell. If it's the latter, then his claim that
> MSVC++5.0 *REFUSED* to compile his program might be among
> the simplest of newbie mistakes. If so, the response that has been
> generated is quite ironic.
>
> ...
> > Of course, but the question was not one of style, but one of legality.
> > The original code is legal and a conforming compiler must compile it. As
> > I said in my previous post, I like the warning that MSVC 6.0 gives, but
> > it should only be a warning.
>
> It would take me hours to set up MSVC++ 5.0 to test this out, but I
> would be willing to bet that this message IS a warning in that
> compiler.
>
> Anyone like to prove me wrong? Please try it and report what happens.

error C2202: 'f' : not all control paths return a value

Does it look like a warning? :-)

Stach
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: jcoffin@taeus.com (Jerry Coffin)
Date: 1999/12/09
Raw View
In article <t71z8x6pbf.fsf@calumny.jyacc.com>, hymie@prolifics.com
says...

[ ... ]

> That actually raises an interesting question. Can undefined behavior
> reach backward in time? That is, suppose that I can prove that my
> program will cause a sequence of legal side effects, but then always
> execute some undefined behavior. Must the compiler ensure that the
> legal side effects happen, or is the prospect of eventual undefinedness
> enough to allow the program to do undefined things immediately?

I'm not sure this has ever been addressed specifically WRT C++, but
IIRC, there was an official clarification (or perhaps a DR) from the C
committee that said, in essence, that if the program executed any code
with undefined behavior, then the behavior of the program as a whole
was undefined.

--
    Later,
    Jerry.

The universe is a figment of its own imagination.


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Steve Clamage <stephen.clamage@sun.com>
Date: 1999/12/11
Raw View
Hyman Rosen wrote:
>
> jcoffin@taeus.com (Jerry Coffin) writes:
> > I _think_ the compiler can reject this program since it can (at least
> > theoretically) determine that there's no way for the program to
> > execute with using undefined behavior.
>
> That actually raises an interesting question. Can undefined behavior
> reach backward in time?

Yes, the compiler is required to generate code that can cause
effects in the past, or undo past effects. This requirement
makes it possible to become very wealthy by having conditional
operations on stock prices or winners of sporting events.

More seriously, the definition of "undefined behavior" is that
the standard places NO REQUIREMENTS on the implementation. The
standad defines semantics and observable effects only for
programs having no undefined behavior.

--
Steve Clamage, stephen.clamage@sun.com
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: christian.bau@isltd.insignia.com (Christian Bau)
Date: 1999/12/11
Raw View
In article <t71z8x6pbf.fsf@calumny.jyacc.com>, Hyman Rosen
<hymie@prolifics.com> wrote:

> jcoffin@taeus.com (Jerry Coffin) writes:
> > I _think_ the compiler can reject this program since it can (at least
> > theoretically) determine that there's no way for the program to
> > execute with using undefined behavior.
>
> That actually raises an interesting question. Can undefined behavior
> reach backward in time? That is, suppose that I can prove that my
> program will cause a sequence of legal side effects, but then always
> execute some undefined behavior. Must the compiler ensure that the
> legal side effects happen, or is the prospect of eventual undefinedness
> enough to allow the program to do undefined things immediately?

As an example: You know that modifying the same object twice without a
sequence point in between is undefined behavior. So the expression (*p)++
+ (*q)++ invokes undefined behavior if p and q point to the same object.

If the compiler can prove that this expression will be evaluated at some
point in the future, then it can safely assume that p != q. So if you
write

   int f (int* p, int* q)
   {
      if (p == q) printf ("p and q are equal\n");
      else printf ("p and q are different\n");

      return (*p)++ + (*q)++;
   }

an optimising compiler can legally replace this with something similar to

   int f (int* p, int* q)
   {
      printf ("p and q are different\n");
      register int tmp1 = *p;
      register int tmp2 = *q;
      *p = tmp1 + 1;
      *q = tmp2 + 1;
      return tmp1 + tmp2;
   }

BTW. One of the most interesting examples of undefined behavior I have
ever seen is this:

   char* p = 1/0;

As 1/0 invokes undefined behavior, a compiler may obviously assume that
1/0 is a constant integer expression with some value. If that value is 0,
then this is legal C/C++. If that value is not zero, then we have a syntax
error.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/12/08
Raw View
In article <BRZNONLmDgsyjN=7gXtrQvYWVeSJ@4ax.com>, Michael Rubenstein
<miker3@ix.netcom.com> writes
>The compiler must generate code unless it can be determined that
>this function will be called with an argument other than 0 or 1.
>There is no requirement in the standard that a function be able
>to accept any possible input value.  This function will produce
>undefined behavior if it is called with an argument other than 0
>or 1, but if it is never called with such a value this code is
>legal.


So what is required of a compiler faced with:

int main (){
  if (false) {
     const int i = 1/0;
     int array[i]
  }
  return 0;
}




Francis Glassborow      Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "AllanW" <AllanW@my-deja.com>
Date: 1999/12/08
Raw View
> Bennett McElwee <bmcelwee@my-deja.com> wrote:
> >> By your reasoning, can the compiler refuse to compile this becuase a
> >> path might exist in the program where p will be a null or
> >> uninitialized pointer?
> >
> >No, because the above is legal C++. Even this code:

Pablo Halpern <phalpern@newview.org> wrote:
> So was the original post, but the MSVC 5.0 compiler refused to compile
> it.

How do you know this? Because Mr. Tsoglin said so?

Meaning no disrespect: It's possible that Mr. Yuri Tsoglin has 25 years
of experience writing C and C++ compilers and a Ph.D. in computer
science. But then again he might be an amateur who started learning
C++ 6 months ago and is facing his first-ever porting problem. From
the original post, we can't tell. If it's the latter, then his claim that
MSVC++5.0 *REFUSED* to compile his program might be among
the simplest of newbie mistakes. If so, the response that has been
generated is quite ironic.

...
> Of course, but the question was not one of style, but one of legality.
> The original code is legal and a conforming compiler must compile it. As
> I said in my previous post, I like the warning that MSVC 6.0 gives, but
> it should only be a warning.

It would take me hours to set up MSVC++ 5.0 to test this out, but I
would be willing to bet that this message IS a warning in that
compiler.

Anyone like to prove me wrong? Please try it and report what happens.

--
Allan_W@my-deja.com is a "Spam Magnet," never read.
Please reply in newsgroups only, sorry.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Bennett McElwee <bmcelwee@my-deja.com>
Date: 1999/12/08
Raw View
Michael Rubenstein <miker3@ix.netcom.com> wrote:
> >> >> int f (int x)
> >> >> {
> >> >>     switch (x) {
> >> >>     case 0:
> >> >>         return 3;
> >> >>     case 1:
> >> >>         return 4;
> >> >>     }
> >> >> }
> The compiler must generate code unless it can be determined that
> this function will be called with an argument other than 0 or 1.
> There is no requirement in the standard that a function be able
> to accept any possible input value.  This function will produce
> undefined behavior if it is called with an argument other than 0
> or 1, but if it is never called with such a value this code is
> legal.

OK, thanks for that. Some simple questions, then, to clarify things
for me (and any kibitzers):

// Program 1
int f() {}
int main() {return 0;}

I (now) think program 1 is legal C++. Am I right? (See my signature.)
(Note that VC++ 6 gives an error here because f() does not return a
value, even though the VC++ docs say this should only be a warning.)

// Program 2
int f() {}
int main() {return f();}

// Program 3
int main() {}

Are programs 2 and 3 legal C++? Obviously, the runtime behaviour of
these programs would be undefined if the compiler produced code for
them. But if I try to compile them, what should the compiler do?
Should it issue a diagnostic, or is its behaviour completely
undefined?

TIA,
Bennett.
--
-- Bennett McElwee
-- I reserve the right to be wrong.


Sent via Deja.com http://www.deja.com/
Before you buy.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: jbarfurth@vossnet.de (Joerg Barfurth)
Date: 1999/12/08
Raw View
Bennett McElwee <bmcelwee@my-deja.com> wrote:

> Are you saying that if a C++ compiler can determine that a program's
> runtime behaviour will be undefined, then the compiler's behaviour is
> undefined?
>
> Please give references into the standard (or anywhere else!) if you
> think they might be helpful...

Look at 1.3.12 undefined behaviour [defns.undefined]

"behaviour such as might arise upon use of an erroneous program
construct or erroneous data, for which this International Standard
imposes no requirements. ...
...[Note: permissible undefined behaviour ranges from ignoring the
situation completely with unpredictable results, ... to terminating a
translation or execution (with the issuance of a diagnostic message)."

Absolutely "no requirements" are imposed on the implementation, which
includes compiler and execution environment.

AFAICS there are also no restrictions on the effort a compiler can make
to determine whether a program causes undefined behaviour...

-- J   rg Barfurth



[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Michael Rubenstein <miker3@ix.netcom.com>
Date: 1999/12/08
Raw View
On 7 Dec 1999 21:58:45 GMT, Christopher Eltschka
<celtschk@physik.tu-muenchen.de> wrote:

>
>"James Kuyper Jr." wrote:
>>
>> sirwillard@my-deja.com wrote:
>> ....
>> > You are joking, right?  The possibility that any instruction, intended
>> > or not, could cocievably cause hardware to overheat and catch fire is
>> > the basis of an urban legend.  In other words, it's not very damn
>> > likely, and you'll be hard pressed to give a single documented
>> > occurrence of this having happened. ...
>>
>> I never said it was likely, only possible. Furthermore, what a computer
>> is capable of doing depends entirely upon what hardware is attached to
>> it, which is something the standard says very little about. I think
>> you'll agree that a computer which has control of a bomb attached to it
>> could trivially blow itself up as a result of undefined behavior.
>
>This reminds me of a real-world case (though not in C++):
>The attached device was not a bomb, but an Ariane V...

Of course if the attached device is a bomb, there are other
possibilities.  Undefined behavior may result in your program not
blowing up :-)



[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Yuri Tsoglin <tyuri@cs.technion.ac.il>
Date: 1999/12/08
Raw View

AllanW wrote:

> How do you know this? Because Mr. Tsoglin said so?
>
> Meaning no disrespect: It's possible that Mr. Yuri Tsoglin has 25 years
> of experience writing C and C++ compilers and a Ph.D. in computer
> science. But then again he might be an amateur who started learning
> C++ 6 months ago and is facing his first-ever porting problem.

Well, maybe you'll not beleive, but I'm doing now M.Sc. in Computer
Science, and I'm writing the thesis project in C++ (and the thesis topic
is writing something like a parser generator, so I have a bit :-) of knowledge
about compilation).

Now, my program has a lot of such switch statements, usually switched
by enumerated types, so it's clear that they are cased by the enum values,
without default. At the start, I used Borland C++ compiler, later I had
to move to Visual 5.0, and the program which had already compiled
successfully with Borland, did not compile because of "Not all control
paths return a value". I had changed it (adding default or adding return
outside the switch). When I moved to Visual 6.0, I noticed that such error
gives no more error but just warning messages.

> From
> the original post, we can't tell. If it's the latter, then his claim that
> MSVC++5.0 *REFUSED* to compile his program might be among
> the simplest of newbie mistakes.

Do you mean I cannot distinguish between warning messages + *generating*
executable and error messages + *not generating* executable by the compiler?

> It would take me hours to set up MSVC++ 5.0 to test this out, but I
> would be willing to bet that this message IS a warning in that
> compiler.

Why? Are you sure MSVC++ cannot have its own bugs? I have already noticed
at least a dozen of non-conformities to the standard in it. For example, it
still doesn't
treat a variable defined within the for-init-statement as local to the loop,
so this function:
void f (void)
{
    int i;
    for (int i=0; i<10; i++)
    ...
}
gives error message:  'i' : redefinition  (this one, like many others, happen
in both 5.0 and 6.0 versions).

Yuri.


[ moderator's note: html attachment deleted.  Please set your
  newsreader to send only plain text with no attachments. -sdc ]


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Michiel Salters <salters@lucent.com>
Date: 1999/12/08
Raw View
Bennett McElwee wrote:

> Ron Natalie <ron@sensor.com> wrote:
> > Be very careful, while undefined behavior may escape detection
> > at runtime, the compiler is under no obligation to even compile
> > it.

> Are you saying that if a C++ compiler can determine that a program's
> runtime behaviour will be undefined, then the compiler's behaviour is
> undefined?

> Please give references into the standard (or anywhere else!) if you
> think they might be helpful...

> Thanks,
> Bennett.

Stronger: Even if a C++ compiler can determine that a program's
runtime behavior will be _DEFINED_, then the compiler's behavior is
_still_ undefined.

The standard allows the compiler to emit as many warnings as it
likes, for any reason it likes ("Warning 0: This program may not
work if the power is down" :-) ). Certainly this must be qualified
as observable behavior, but the standard has nothing to say about
it -> undefined behavior! Only in a few cases a demand is made
on the output of the compiler; Good input should yield a working
program & some errors must produce a "diagnostic" (could be a
^G beep :-)

Michiel Salters


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Al Stevens" <alstevens@midifitz.com>
Date: 1999/12/08
Raw View
>> So was the original post, but the MSVC 5.0 compiler refused to compile
>> it.
>
>How do you know this? Because Mr. Tsoglin said so?

Mr. Tsoglin reported the situation accurately. The file seems to compile OK
but the error shows up in the link, which is what Mr. Tsoglin reported. The
compiler fails to instantiate everything that the program's use of the
template requires in this particular case (or however you're supposed to say
that).

>> Of course, but the question was not one of style, but one of legality.
>> The original code is legal and a conforming compiler must compile it. As
>> I said in my previous post, I like the warning that MSVC 6.0 gives, but
>> it should only be a warning.
>
>It would take me hours to set up MSVC++ 5.0 to test this out, but I
>would be willing to bet that this message IS a warning in that
>compiler.
>
>Anyone like to prove me wrong? Please try it and report what happens.

Mr Tsoglin is right again. MSVC++ 5.0 reports the message as an error and
refuses to compile the program. It is a well-known behavior with 5.0. In 6.0
MS changed the behavior to issue a warning and compile the program.




[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Al Stevens" <alstevens@midifitz.com>
Date: 1999/12/08
Raw View
>// Program 3
>int main() {}
>
>Are programs 2 and 3 legal C++?

Program 3 is legal. main is permitted to omit the return statement
(3.6.1.5). The standard includes many examples that have main functions
without return statements. I've read some emotional opinions about that
practice, but the standard is clear. Dropping off the bottom of main without
a return statement is the same as saying return 0;




[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: jcoffin@taeus.com (Jerry Coffin)
Date: 1999/12/08
Raw View
In article <82lgtj$ff$1@nnrp1.deja.com>, bmcelwee@my-deja.com says...

[ ... ]

> // Program 1
> int f() {}
> int main() {return 0;}
>
> I (now) think program 1 is legal C++. Am I right? (See my signature.)

Yes, it looks legal to me.

> // Program 2
> int f() {}
> int main() {return f();}

I _think_ the compiler can reject this program since it can (at least
theoretically) determine that there's no way for the program to
execute with using undefined behavior.

> // Program 3
> int main() {}

This is a valid program with (almost) entirely well-defined results.
The standard has a special clause that if execution flows off the end
of main, it's equivalent to returning 0, so there's really no question
about this one at all; main is special in this regard.

--
    Later,
    Jerry.

The universe is a figment of its own imagination.


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Michael Rubenstein <miker3@ix.netcom.com>
Date: 1999/12/08
Raw View
On 8 Dec 1999 00:17:00 GMT, Francis Glassborow
<francis@robinton.demon.co.uk> wrote:

>
>In article <BRZNONLmDgsyjN=7gXtrQvYWVeSJ@4ax.com>, Michael Rubenstein
><miker3@ix.netcom.com> writes
>>The compiler must generate code unless it can be determined that
>>this function will be called with an argument other than 0 or 1.
>>There is no requirement in the standard that a function be able
>>to accept any possible input value.  This function will produce
>>undefined behavior if it is called with an argument other than 0
>>or 1, but if it is never called with such a value this code is
>>legal.
>
>
>So what is required of a compiler faced with:
>
>int main (){
>  if (false) {
>     const int i = 1/0;
>     int array[i]
>  }
>  return 0;
>}

As I read the standard, a diagnostic is required (5):

 If during the evaluation of an expression, the result is
 not mathematically defined or not in the range of
 representable values for its type, the behavior is
 undefined, unless such an expression is a constant
 expression (5.19), in which case the program is ill
 formed


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Jim Hyslop <jim.hyslop@leitch.com>
Date: 1999/12/09
Raw View
In article <384D01F5.64FF9139@cs.technion.ac.il>,
  Yuri Tsoglin <tyuri@cs.technion.ac.il> wrote:
>
>
> AllanW wrote:
[snip]
> > Interesting that this discussion drifted into the definition of
> > "undefined
> > behavior" when the answer is so simple.
>
> Interesting that this is exactly what I meant to ask in my initial
> post
> in this thread - I wanted to know what "undefined behavior" means, and
> I gave the
> above program only as an example for the general problem.
> If I don't know the answer, I don't know what *any* compiler should do
> with
> this program, and what I have to expect from a compiler.
Quite simply, you cannot necessarily predict what a given compiler will
do with undefined behaviour.  That's why it is best to write your code
so that you never depend on the results of undefined behaviour.

This also means, of course, that you have to be thoroughly familiar with
the rules, so you know when what you're doing will invoke undefined
behaviour.

> May it reject the program? - then I have to change it to be sure that
> any compiler
> will compile it (even if it will give a warning, but still compile).
> So, my main question actually was: "May a compiler reject a program
> which
> *can* (but not necessarily) have undefined behavior?"
[snip]

>From my readings of the Standard, it usually will only require a
diagnostic message when the compiler can detect most, if not all,
violations of a particular rule.   If there is a possibility that the
compiler might detect the violation under some circumstances, but not
detect it under other circumstances, then the compiler is not usually
required to issue any diagnostic.

That's why, for example, your original code is only a warning - and most
likely, a low-level warning:  the compiler cannot determine all possible
ways your code will be used, so your code may be correct and not invoke
undefined behaviour.

And, it actually makes sense for a compiler *not* to attempt to detect
all possible invocations of undefined behaviour.  A diagnostic message
that only shows up sometimes is not really much use to anyone.  You, the
programmer, would never know if the absence of a particular warning was
because your code is correct, or because the compiler was unable to
determine if you invoked undefined behaviour.

For example, consider this code:

// program 1
void f(int *i)
{
   *i = 99;
}

int main()
{
   f(0);
}

Clearly, this program will invoke undefined behaviour.  Suppose we have
a compiler that is smart enough to detect this, and issues a diagnostic.
Great - we see the warning/error, fix up our program and carry on.

However, consider what happens when f() is moved into a separate
translation unit:

// program 2

// file1.cpp
void f(int *i)
{
   *i = 99;
}

// file2.cpp
void f(int *i);
int main()
{
   f(0);
}

This program is functionally identical to the first one.  In this
scenario, though, it is impossible for the compiler to determine if the
program will invoke undefined behaviour.  The linker might be able to
detect it, but only by poking around through every single source file
that uses f() and seeing if a NULL pointer is used.  This would be
horrendously complex in a program involving many object files with many
calls to the function; and perhaps even impossible if f() is placed in a
library, or if the argument passed to f() is the return value of another
function, which itself is the return value of another function, and so
on [e.g. f(g(h(i()))); ].

So, the compiler has no choice but to accept the program and compile it
without any diagnostics.  Well, I suppose it could issue "Warning:
Unable to determine if usage of f() at line 5 in function main() invokes
undefined behaviour" but that message would pop up so frequently in a
"real" program, it would be next to useless.

You now have a compiler that lulls you into a false sense of security
about the program.  You know that the compiler will issue a diagnostic
for program (1), so you innocently assume that, since program (2) does
not cause the compiler to issue any diagnostics, program (2) must be
correct.

--
Jim
I ignore all email from recruitment agencies.
Please do not send me email with questions - post
here.


Sent via Deja.com http://www.deja.com/
Before you buy.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Hyman Rosen <hymie@prolifics.com>
Date: 1999/12/09
Raw View
jcoffin@taeus.com (Jerry Coffin) writes:
> I _think_ the compiler can reject this program since it can (at least
> theoretically) determine that there's no way for the program to
> execute with using undefined behavior.

That actually raises an interesting question. Can undefined behavior
reach backward in time? That is, suppose that I can prove that my
program will cause a sequence of legal side effects, but then always
execute some undefined behavior. Must the compiler ensure that the
legal side effects happen, or is the prospect of eventual undefinedness
enough to allow the program to do undefined things immediately?
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: pmscott@dera.gov.uk (Paul Scott)
Date: 1999/12/09
Raw View
Francis Glassborow wrote:
>

>So what is required of a compiler faced with:
>
>int main (){
>  if (false) {
>     const int i = 1/0;
>     int array[i]
>  }
>  return 0;
>}
>

Interesting results from g++ (egcs 1.1.2)

g++ tmp.cc:

tmp.cc: In function `int main()':
tmp.cc:3: warning: division by zero in `1 / 0'


g++ -Wall tmp.cc:

tmp.cc: In function `int main()':
tmp.cc:3: warning: division by zero in `1 / 0'
tmp.cc:4: warning: unused variable `int array[(((1 / 0) - 1) + 1)]'


-O makes no difference to either.

What's going on here then?

--
Paul Scott
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: sirwillard@my-deja.com
Date: 1999/12/06
Raw View
In article <38444E8E.892C6CC9@wizard.net>,
  James Kuyper <kuyper@wizard.net> wrote:
>
> Steve Clamage wrote:
> ...
> > "Undefined behavior" is a technical term meaning that that standard
> > places no requirements on the implementation.  "No requirements"
> > means exactly that -- any behavior at all (refuse to compile, issue
> > a warning, crash at run time, whatever) is allowed by the standard.
> >
> > The implementation can refuse to compile the code, issue messages
> > at compile time, or at run time, or not do anything special. As a
> > customer of the compiler vendor you should expect something
> > reasonable, as opposed to your computer catching fire.
>
> Not true in general. Code which allows undefined behaviour could, in
> general, have as one of its possible consequences the transmission to
> any hardware attached to your computer any messages that hardware is
> capable of recieving. It's quite possible that the messages sent could
> put the hardware into a mode where it overheats and bursts into flame.
> On high-end machines there are barriers to prevent this, but it's
still
> possible (though less likely) for defective code to find any holes
that
> might exist in those barriers. Defective code on modern machines can
> execute billions of unintended instructions a second; I wouldn't be
> willing to guarantee that such code will halt before executing a
> dangerous instruction sequence.

You are joking, right?  The possibility that any instruction, intended
or not, could cocievably cause hardware to overheat and catch fire is
the basis of an urban legend.  In other words, it's not very damn
likely, and you'll be hard pressed to give a single documented
occurrence of this having happened.  The idea that software can damage
hardware in any way is far fetched.  The only thing not far fetched is
that something unwanted may occur, such as formatting your hard drive,
shutting the computer down hard stop, etc.

That said, the original thinking was reasonable.  Compiler/library
vendors should strive to reduce the risk involved in "undefined
behavior" sections of the standard when it's possible.  This particular
example is a classic case where it is possible to define behavior
better than "possibly wipe out his disk", namely the issuance of a
diagnostic at compile time.


Sent via Deja.com http://www.deja.com/
Before you buy.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Anders J. Munch" <andersjm@post.tele.dk>
Date: 1999/12/06
Raw View
Steve Clamage wrote in message <3844194B.BFF0A7D0@sun.com>...
>If there is a control path that can "fall off the end" of the
>function without returning a value, the behavior of the program
>is undefined. The reason it is undefined is that in general it
>is impossible to know at compile time whether such a path exists.
> int g()
> {
> int k = 0;
> cin >> k;
> if( k > 0 )
> return k;
> }
>
>"Undefined behavior" is a technical term meaning that that standard
>places no requirements on the implementation.  "No requirements"
>means exactly that -- any behavior at all (refuse to compile, issue
>a warning, crash at run time, whatever) is allowed by the standard.

I beg to differ.

"undefined behaviour" is not a property of a single program element
such as Yuri's f() or your g() function.  It is a property of an
execution path of a complete program.  A program containing a program
element prone to undefined behaviour may still be a well-formed
C++-program, and no actual undefined behaviour will occur unless
one of the programs possible execution sequences invokes it.

Here's Yuri's function again, augmented to be a complete program:
int f (int x)
{
    switch (x) {
    case 0:
        return 3;
    case 1:
        return 4;
    }
}
int main()
{
    return f(0);
}

This is a well-formed program, and since no possible execution paths
invoke undefined behaviour, an conforming implementation is required
to execute it producing the appropriate observable behaviour.

At least that's how I read the standard.  Since several people who
usually know what they're talking about (Steve et al) have expressed a
different opinion in this thread, I'd be interested to hear what they
base it on.  In particular, is a conforming implementation allowed to
reject the following program based on "i = j" invoking undefined
behaviour?

int main()
{
  int i,j;
  if(false) i = j;
}

- Anders
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Yuri Tsoglin <tyuri@cs.technion.ac.il>
Date: 1999/12/06
Raw View
Francis Glassborow wrote:

> >2. This code:
> >int f (int x)
> >{
> >    switch (x) {
> >    case 0:
> >        return 3;
> >    case 1:
> >        return 4;
> >    }
> >}
> >
> >gave error message in Visual C++ 5.0 and did not compile:
> >'f' : not all control paths return a value
>
> which is perfectly true, if x is neither 3 nor 4 what gets returned?

Maybe I know that x is either of the two (no matter how do I know)?
A better example could be:

    enum color { red, yellow, green };
    color x;
    switch (x) {
        case red: return "R";
        case yellow: return "Y";
        case green: return "G";
    };

I understand that in general even here x can get a value which is neither
red, yellow, nor green,
but if I know that in my specific program it will never happen, why would I
write the "default" for it?

> >In Visual C++ 6.0 it gives the same message but as warning (not error)
> >and compiles!
>
> All the standard requires is a diagnostic, having given such (and a
> warning suffices) it can then do whatever it likes.  Perhaps the
> behaviour of 6.0 would be preferred by those that like walking on the
> edge of precipices.

Does it mean that if I write a program which I want to compile on any C++
compiler
(assuming the compiler works according to the standard), I cannot have such
things in the program?
But if I am *absolutely* sure that there are no other cases, the only
reasonable thing I can do is to add:

    default: throw SomeException();

Is the following function also incorrect, according to the standard?
int f ()
{
    switch (int x=1) {
        case 1:
            return 1;
    }
}
It seems very strange if it is.

> >Which one does it correct?
>
> Both:)
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Steve Clamage <stephen.clamage@sun.com>
Date: 1999/12/06
Raw View
Christopher Eltschka wrote:
>
> Steve Clamage wrote:
> >
> >
> > If there is a control path that can "fall off the end" of the
> > function without returning a value, the behavior of the program
> > is undefined.
>
> [...]
>
> > "Undefined behavior" is a technical term meaning that that standard
> > places no requirements on the implementation.  "No requirements"
> > means exactly that -- any behavior at all (refuse to compile, issue
> > a warning, crash at run time, whatever) is allowed by the standard.
> >
> > The implementation can refuse to compile the code, issue messages
> > at compile time, or at run time, or not do anything special.
>
> [...]
>
> Is an implementation really allowed to refuse to compile
> this function?
> I thought the undefined behaviour happens only if the path
> is actually taken. So for the function f above, the compiler
> would have to proof that this function is *ever* called with
> a value of x other than 1 or 2, to legally refuse compiling.

I was describing the rules for undefined behavior. If the function
is called in such a way that the behavior is defined, there is
no problem, and no, the compiler cannot refuse to compile it.

--
Steve Clamage, stephen.clamage@sun.com
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Michael Cook <cook@sightpath.com>
Date: 1999/12/06
Raw View
sirwillard@my-deja.com writes:

> You are joking, right?  The possibility that any instruction, intended
> or not, could cocievably cause hardware to overheat and catch fire is
> the basis of an urban legend.  In other words, it's not very damn
> likely, and you'll be hard pressed to give a single documented
> occurrence of this having happened.  The idea that software can damage
> hardware in any way is far fetched.  The only thing not far fetched is
> that something unwanted may occur, such as formatting your hard drive,
> shutting the computer down hard stop, etc.

On multiple occasions, I have written drivers for custom hardware
for which the hardware engineer told me, "don't write X to this
register, or you'll damage the hardware."  Usually, it was a bus
contention issue where bus drivers would end up working against each
other, and could burn each other out.  So, undefined behavior really
could mean your computer catches fire.

M.


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1999/12/06
Raw View
sirwillard@my-deja.com wrote:

[...]

> occurrence of this having happened.  The idea that software can damage
> hardware in any way is far fetched.  The only thing not far fetched is
> that something unwanted may occur, such as formatting your hard drive,
> shutting the computer down hard stop, etc.

What happens if you drive a fixed frequency monitor connected
to a modern graphics card at a high frequency?


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Bennett McElwee <bmcelwee@my-deja.com>
Date: 1999/12/06
Raw View

> Consider this code, for example:
>  void g(int *p)
>       {
>    *p = 5;
>  }
> By your reasoning, can the compiler refuse to compile this becuase a
> path might exist in the program where p will be a null or
> uninitialized pointer?

No, because the above is legal C++. Even this code:

   void h() {
      int* p = 0;
      *p = 0;
   }

which is guaranteed to misbehave at runtime, will compile perfectly
well because the compiler can unambiguously translate the C++ into
machine code. Everything is well-defined at compile-time, even though
this results (I think) in undefined behaviour at runtime.

However, in the case of

> >> int f (int x)
> >> {
> >>     switch (x) {
> >>     case 0:
> >>         return 3;
> >>     case 1:
> >>         return 4;
> >>     }
> >> }

the compiler can't generate code, because the function must always
return some value. Perhaps it could just return an uninitialised
value of the appropriate type; but what if the function was meant
to return a reference? an uninitialised reference is completely
useless.

> I would expect a conforming compiler *must* compile Yuri's code
> *unless* it can prove that x will be other than 0 or 1 at runtime.

Maybe in some programs the compiler could determine that 0 and 1
are the only cases, but this falls under the realm of optimisation.

> In fact, if f is called with a boolean expression argument (e.g. in
> portable code that works with compilers that don't yet support bool),
> you might be 100% certain that x is either 0 or 1.

In this case you would probably write something like

int f (int x)
{
    switch (x) {
    case 0:
        return 3;
    default:
        return 4;
    }
}

Or even: int f (int x) { return x ? 4 : 3; } or whatever...

Cheerio,
Bennett.
--
-- Bennett McElwee
-- I reserve the right to be wrong.


Sent via Deja.com http://www.deja.com/
Before you buy.


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Ron Natalie <ron@sensor.com>
Date: 1999/12/06
Raw View


Bennett McElwee wrote:

>
> No, because the above is legal C++. Even this code:
>
>    void h() {
>       int* p = 0;
>       *p = 0;
>    }
>
> which is guaranteed to misbehave at runtime, will compile perfectly
> well because the compiler can unambiguously translate the C++ into
> machine code. Everything is well-defined at compile-time, even though
> this results (I think) in undefined behaviour at runtime.
>

Be very careful, while undefined behavior may escape detection
at runtime, the compiler is under no obligation to even compile
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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Jim Hyslop <jim.hyslop@leitch.com>
Date: 1999/12/07
Raw View
In article <3845C8BB.2083CEC5@cs.technion.ac.il>,
  Yuri Tsoglin <tyuri@cs.technion.ac.il> wrote:
[snip]
> Maybe I know that x is either of the two (no matter how do I know)?
> A better example could be:
>
>     enum color { red, yellow, green };
>     color x;
>     switch (x) {
>         case red: return "R";
>         case yellow: return "Y";
>         case green: return "G";
>     };
>
> I understand that in general even here x can get a value which is
> neither
> red, yellow, nor green,
> but if I know that in my specific program it will never happen, why
> would I
> write the "default" for it?
For one, defensive programming.  Suppose the enum is defined in a header
file, not in the same source file.  Suppose further that the function in
which your code snippet appears must return a valid string no matter
what value is passed to it.  Now suppose someone adds "purple" to the
enums - guess what?  Your code just broke, and broke in such a way that
its behaviour is now completely unpredictable.  Adding a
   default: return "?";

makes your function behave predictably no matter what happens to the
enum.

For two, just to shut up the damn compiler ;-)

[snip]
> Does it mean that if I write a program which I want to compile on any
> C++
> compiler
> (assuming the compiler works according to the standard), I cannot have
> such
> things in the program?
> But if I am *absolutely* sure that there are no other cases, the only
> reasonable thing I can do is to add:
>
>     default: throw SomeException();
That's defensive programming again, but your compiler might still
complain if it doesn't clue in to the fact that 'throw' terminates the
function.  Your best bet, if you want to avoid all warnings, is to put
in a return statement ;-)

> Is the following function also incorrect, according to the standard?
> int f ()
> {
>     switch (int x=1) {
>         case 1:
>             return 1;
>     }
> }
> It seems very strange if it is.
f() invokes "undefined behaviour" - but, since "undefined behaviour"
means anything at all can happen, a compiler might replace that function
with the equivalent of:
int f()
{
   return 1;
}

--
Jim
I ignore all email from recruitment agencies.
Please do not send me email with questions - post
here.


Sent via Deja.com http://www.deja.com/
Before you buy.


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "AllanW" <AllanW@my-deja.com>
Date: 1999/12/07
Raw View
Yuri Tsoglin <tyuri@cs.technion.ac.il> wrote in message
news:3843E296.9068EB0D@cs.technion.ac.il...
...
> 2. This code:
> int f (int x)
> {
>     switch (x) {
>     case 0:
>         return 3;
>     case 1:
>         return 4;
>     }
> }

Both Microsoft Visual C++ 5.0 and Microsoft Visual C++ 6.0 define this
condition as a warning. This class of warning is what I call "protect the
programmer from himself" warnings. Consider this code:

    void assert_zero(int x) {
        if (x=0) { // Oops
            std::cout << "ERROR! assert_zero() failed!" << std::endl;
            abort(1);
        }
    }

If you enable warnings, Microsoft Visual C++ (and many other compilers) warn
you that the if() condition uses the assignment operator (=) instead of the
equality operator (==). Without the warning -- well, this is legal C++ code,
but the if condition never fires. You might never notice the problem until
your customer calls in to complain.

It's a good idea to enable all of these warnings, and then fix your code to
eliminate them. At first this seems to be quite a pain, but eventually some
of the changes will force you to clean up bugs that you didn't even know
were there. Even if that never happens, it at least makes your code easier
for other programmers to parse.

"But," I hear you cry, "shouldn't that be just a warning? Instead, it...
> gave error message in Visual C++ 5.0 and did not compile:
>     'f' : not all control paths return a value
> In Visual C++ 6.0 it gives the same message but as warning (not error)
> and compiles!
> Which one does it correct?

Check your compiler options. If that condition gave you an error message in
5.0, then your 5.0 options include "flag all warnings as errors." Turn this
off and the code will compile.

Interesting that this discussion drifted into the definition of "undefined
behavior" when the answer is so simple.




[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Gavin Collings <gcollings@sperry-sun.co.uk>
Date: 1999/12/07
Raw View
In article <oBiPsfAK2SR4Ew04@robinton.demon.co.uk>,
  Francis Glassborow <francisG@robinton.demon.co.uk> wrote:
> >int f (int x)
> >{
> >    switch (x) {
> >    case 0:
> >        return 3;
> >    case 1:
> >        return 4;
> >    }
> >}
> which is perfectly true, if x is neither 3 nor 4 what gets returned?
>
> ...  Perhaps the behaviour of 6.0 would be preferred by those that
> like walking on the edge of precipices.

And how easy it is to walk off the edge!  What does get returned if x
is either 3 or 4?

--
Gavin Collings
gcollings@sperry-sun.co.uk


Sent via Deja.com http://www.deja.com/
Before you buy.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Bennett McElwee <bmcelwee@my-deja.com>
Date: 1999/12/07
Raw View
Ron Natalie <ron@sensor.com> wrote:
> Be very careful, while undefined behavior may escape detection
> at runtime, the compiler is under no obligation to even compile
> it.

Are you saying that if a C++ compiler can determine that a program's
runtime behaviour will be undefined, then the compiler's behaviour is
undefined?

Please give references into the standard (or anywhere else!) if you
think they might be helpful...

Thanks,
Bennett.
--
-- Bennett McElwee
-- I reserve the right to be wrong.


Sent via Deja.com http://www.deja.com/
Before you buy.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Michael Rubenstein <miker3@ix.netcom.com>
Date: 1999/12/07
Raw View
On 6 Dec 1999 19:25:05 GMT, Bennett McElwee
<bmcelwee@my-deja.com> wrote:

>However, in the case of
>
>> >> int f (int x)
>> >> {
>> >>     switch (x) {
>> >>     case 0:
>> >>         return 3;
>> >>     case 1:
>> >>         return 4;
>> >>     }
>> >> }
>
>the compiler can't generate code, because the function must always
>return some value. Perhaps it could just return an uninitialised
>value of the appropriate type; but what if the function was meant
>to return a reference? an uninitialised reference is completely
>useless.

Sorry, an earlier version of this article escaped before I was
done with it.

The compiler must generate code unless it can be determined that
this function will be called with an argument other than 0 or 1.
There is no requirement in the standard that a function be able
to accept any possible input value.  This function will produce
undefined behavior if it is called with an argument other than 0
or 1, but if it is never called with such a value this code is
legal.  If your compiler does not compile the program

 int f(int x)
 {
   switch (x) {
     case 0:
       return 3;
     case 1:
       return 4;
   }
 }

 int main()
 {
   f(0);
   return 0;
 }

it is broken.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "James Kuyper Jr." <kuyper@wizard.net>
Date: 1999/12/07
Raw View
sirwillard@my-deja.com wrote:
....
> You are joking, right?  The possibility that any instruction, intended
> or not, could cocievably cause hardware to overheat and catch fire is
> the basis of an urban legend.  In other words, it's not very damn
> likely, and you'll be hard pressed to give a single documented
> occurrence of this having happened. ...

I never said it was likely, only possible. Furthermore, what a computer
is capable of doing depends entirely upon what hardware is attached to
it, which is something the standard says very little about. I think
you'll agree that a computer which has control of a bomb attached to it
could trivially blow itself up as a result of undefined behavior.
Devices should be accessed directly only by device drivers that can be
trusted to send only safe control sequences, but not all systems are
that sophisticated. PC/DOS sure wasn't, for instance. You're probably
used to systems with a large insulating layer separating the hardware
from user code, but the standard doesn't require that.

I think that any degree of complacency about the safety of undefined
behavior is dangerous. Just a few years ago, I wrote a program that, due
to a memory violation, brought down the entire local computer network
every time I ran it. Now, I'll grant you that the network was being run
by the lowest bidder on a government contract ;-) but they still had to
pass government audits and meet government requirements on the
experience levels of the personnel operating it. I knew there was a
problem in my code, but it wasn't running with any special privileges,
and wasn't using any unusual OS features. I couldn't believe the system
was that poorly insulated from my code, which is why it took me about
two dozen debugging runs before I realized that I was causing the system
failures.

> ... The idea that software can damage
> hardware in any way is far fetched. ...

Well, I've owned SCSI HBAs, graphics cards, and monitors whose
documentation warned me that attempting to operate them in the wrong
mode (which was under software control) could physically damage them.
Were the manufacturers lying to me?

> ... The only thing not far fetched is
> that something unwanted may occur, such as formatting your hard drive,
> shutting the computer down hard stop, etc.

I agree - that's far more likely, but not infinitely more likely.

> That said, the original thinking was reasonable.  Compiler/library
> vendors should strive to reduce the risk involved in "undefined
> behavior" sections of the standard when it's possible.  This particular
> example is a classic case where it is possible to define behavior
> better than "possibly wipe out his disk", namely the issuance of a
> diagnostic at compile time.

However, in general it's dangerous to rely on this, and a bad idea for
the standard to require it. In many cases, undefined behavior can be
expensive to detect automatically; in some cases it's literally
impossible, requiring the equivalent of solving the halting problem.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: pmscott@dera.gov.uk (Paul Scott)
Date: 1999/12/07
Raw View
Michael Cook wrote:
>
>sirwillard@my-deja.com writes:
>
>> You are joking, right?  The possibility that any instruction, intended
>> or not, could cocievably cause hardware to overheat and catch fire is
>> the basis of an urban legend.  In other words, it's not very damn
>> likely, and you'll be hard pressed to give a single documented
>> occurrence of this having happened.  The idea that software can damage
>> hardware in any way is far fetched.  The only thing not far fetched is
>> that something unwanted may occur, such as formatting your hard drive,
>> shutting the computer down hard stop, etc.
>
>On multiple occasions, I have written drivers for custom hardware
>for which the hardware engineer told me, "don't write X to this
>register, or you'll damage the hardware."  Usually, it was a bus
>contention issue where bus drivers would end up working against each
>other, and could burn each other out.  So, undefined behavior really
>could mean your computer catches fire.
>

I *personally* have set fire to a monitor by misprogramming a graphics card.

I'll come round and show you on your PC if you like, sirwilly.

--
Paul Scott
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Michael Ball <ball@acm.org>
Date: 1999/12/07
Raw View
sirwillard@my-deja.com wrote:

> You are joking, right?  The possibility that any instruction, intended
> or not, could cocievably cause hardware to overheat and catch fire is
> the basis of an urban legend.

Catch fire?  Perhaps.  Damage the hardware? Definately possible.  I
remember
a military maching I worked on where the idle loop could not be the
usual

 A: JMP  A

because that would exercise a single location in the core memory too
often
causing the cores at that location to overheat and damage themselves.
You had to write

 A: JMP B
 B: JMP A

I've also worked on early microcomputers where misprogramming the
display
could burn out the monitor.

It's such cases, which are true, that give the old joke about the "HCF"
(Halt and Catch Fire) enough teeth to be funny.

Michael Ball
Sun Microsystems Inc.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Jim Hyslop <jim.hyslop@leitch.com>
Date: 1999/12/07
Raw View
In article <823ee0$f1j$1@nnrp1.deja.com>,
  sirwillard@my-deja.com wrote:
[snip]
> You are joking, right?  The possibility that any instruction, intended
> or not, could cocievably cause hardware to overheat and catch fire is
> the basis of an urban legend.  In other words, it's not very damn
> likely, and you'll be hard pressed to give a single documented
> occurrence of this having happened.  The idea that software can damage
> hardware in any way is far fetched.
Not at all.  One of my reference books (unfortunately, I can't find
which one it is, so I can't give the author proper attribution), related
an anecdote about a computer operator who once made the same claim to
the author, who was a junior programmer at the time.  The author then
put together a simple program that went down the line of tape drives,
one at a time, and snapped the tape in each drive.

Also consider what would happen if a program used an EEPROM, with a
limited number of write cycles available, as a buffer for incoming data
on a very busy line.  It wouldn't take long for the EEPROM to fail.

So, while it may be _difficult_ for software to damage hardware, never
say "never" ;-)

[snip]

--
Jim
I ignore all email from recruitment agencies.
Please do not send me email with questions - post
here.


Sent via Deja.com http://www.deja.com/
Before you buy.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Yuri Tsoglin <tyuri@cs.technion.ac.il>
Date: 1999/12/07
Raw View
--------------5E0E6C29CF709F90CB14A97A
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Bennett McElwee wrote:

> > Consider this code, for example:
> >       void g(int *p)
> >       {
> >         *p = 5;
> >       }
> > By your reasoning, can the compiler refuse to compile this becuase a
> > path might exist in the program where p will be a null or
> > uninitialized pointer?
>
> No, because the above is legal C++.
> However, in the case of
>
> > >> int f (int x)
> > >> {
> > >>     switch (x) {
> > >>     case 0:
> > >>         return 3;
> > >>     case 1:
> > >>         return 4;
> > >>     }
> > >> }
>
> the compiler can't generate code, because the function must always
> return some value. Perhaps it could just return an uninitialised
> value of the appropriate type; but what if the function was meant
> to return a reference? an uninitialised reference is completely
> useless.

But what's the difference between these two examples?? In both, undefined
behavior is possible (in the first example, it's in the case that p is 0,
and in the second it's in the case that x is neither 0 nor 1), but both are
"legal C++", as you say.

> > I would expect a conforming compiler *must* compile Yuri's code
> > *unless* it can prove that x will be other than 0 or 1 at runtime.

I agree, but this would mean that all such decisions would be made by the
linker,
because it depends on all the compilation units (maybe, *another* compilation
unit
calls, say,  f(2) or  g(0) ), unless the function has internal linkage.

So, the best solution seems to be giving a warning in all such cases, but
*not* rejecting the program.
I am not sure at all that in general it is *possible* to make such proofs (it
seems like "NP-complete"
or even "halting problem", isn't it :-)? )

Maybe, another solution (for compiler) is to add some automatic run-time
action in the undefined behavior cases,
for example to add at the end of the function an exception throw (which will
be thrown in any case we got
to that point, that is didn't return a value).

Yuri.

P.S. Sorry for my bad English (also for my previous and future posts).

--------------5E0E6C29CF709F90CB14A97A
Content-Type: text/html; charset=us-ascii
Content-Transfer-Encoding: 7bit

<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
Bennett McElwee wrote:
<blockquote TYPE=CITE>> Consider this code, for example:
<br>>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void g(int *p)
<br>>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {
<br>>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *p = 5;
<br>>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
<br>> By your reasoning, can the compiler refuse to compile this becuase
a
<br>> path might exist in the program where p will be a null or
<br>> uninitialized pointer?
<p>No, because the above is legal C++.
<br>However, in the case of
<p>> >> int f (int x)
<br>> >> {
<br>> >>&nbsp;&nbsp;&nbsp;&nbsp; switch (x) {
<br>> >>&nbsp;&nbsp;&nbsp;&nbsp; case 0:
<br>> >>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 3;
<br>> >>&nbsp;&nbsp;&nbsp;&nbsp; case 1:
<br>> >>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 4;
<br>> >>&nbsp;&nbsp;&nbsp;&nbsp; }
<br>> >> }
<p>the compiler can't generate code, because the function must always
<br>return some value. Perhaps it could just return an uninitialised
<br>value of the appropriate type; but what if the function was meant
<br>to return a reference? an uninitialised reference is completely
<br>useless.</blockquote>
But what's the difference between these two examples?? In both, undefined
<br>behavior is possible (in the first example, it's in the case that p
is 0,
<br>and in the second it's in the case that x is neither 0 nor 1), but
both are
<br>"legal C++", as you say.
<blockquote TYPE=CITE>> I would expect a conforming compiler *must* compile
Yuri's code
<br>> *unless* it can prove that x will be other than 0 or 1 at runtime.</blockquote>
I agree, but this would mean that all such decisions would be made by the
linker,
<br>because it depends on all the compilation units (maybe, *another* compilation
unit
<br>calls, say,&nbsp; <tt>f(2) </tt>or&nbsp; <tt>g(0) </tt>), unless the
function has internal linkage.
<p>So, the best solution seems to be giving a warning in all such cases,
but *not* rejecting the program.
<br>I am not sure at all that in general it is *possible* to make such
proofs (it seems like "NP-complete"
<br>or even "halting problem", isn't it :-)? )
<p>Maybe, another solution (for compiler) is to add some automatic run-time
action in the undefined behavior cases,
<br>for example to add at the end of the function an exception throw (which
will be thrown in any case we got
<br>to that point, that is didn't return a value).
<p>Yuri.
<p>P.S. Sorry for my bad English (also for my previous and future posts).</html>

--------------5E0E6C29CF709F90CB14A97A--
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: phalpern@newview.org (Pablo Halpern)
Date: 1999/12/07
Raw View
Bennett McElwee <bmcelwee@my-deja.com> wrote:

>
>
>> Consider this code, for example:
>>  void g(int *p)
>>       {
>>    *p = 5;
>>  }
>> By your reasoning, can the compiler refuse to compile this becuase a
>> path might exist in the program where p will be a null or
>> uninitialized pointer?
>
>No, because the above is legal C++. Even this code:

So was the original post, but the MSVC 5.0 compiler refused to compile
it.

>   void h() {
>      int* p = 0;
>      *p = 0;
>   }
>
>which is guaranteed to misbehave at runtime, will compile perfectly
>well because the compiler can unambiguously translate the C++ into
>machine code. Everything is well-defined at compile-time, even though
>this results (I think) in undefined behaviour at runtime.

Yes, the compiler *could* produce instructions for it, but it is
guaranteed undefined behavior, so the compiler is permitted to reject
it.

>However, in the case of
>
>> >> int f (int x)
>> >> {
>> >>     switch (x) {
>> >>     case 0:
>> >>         return 3;
>> >>     case 1:
>> >>         return 4;
>> >>     }
>> >> }
>
>the compiler can't generate code, because the function must always
>return some value. Perhaps it could just return an uninitialised
>value of the appropriate type; but what if the function was meant
>to return a reference? an uninitialised reference is completely
>useless.

This is a specious argument. First of all the proof that the compiler
*can* generate code for the above is that most compilers *do* generate
code for the above. The compiler doesn't have to do anything reasonable
with code that drops off the end of the switch. If you are worried about
it, though, the compiler could generate an abort if it wants.

The above is no less legal C++ than the first example in this post. The
behavior is well defined for the case where x is 0 or 1, so if x is
never something else, then the compiler must accept it.

>> I would expect a conforming compiler *must* compile Yuri's code
>> *unless* it can prove that x will be other than 0 or 1 at runtime.
>
>Maybe in some programs the compiler could determine that 0 and 1
>are the only cases, but this falls under the realm of optimisation.

No the optimization is the attempt to diagnose undefined behavior at
compile time. If you skip the optimization, you can either diagnose the
undefined behavior (if any) at run time or leave it undiagnosed. What
you cannot do is assume it is undefined when it might be valid. The
compiler is not required to prove that code works in order to compile
it, but it must prove that code is broken in order to refuse to compile
it.

>> In fact, if f is called with a boolean expression argument (e.g. in
>> portable code that works with compilers that don't yet support bool),
>> you might be 100% certain that x is either 0 or 1.
>
>In this case you would probably write something like
>
>int f (int x)
>{
>    switch (x) {
>    case 0:
>        return 3;
>    default:
>        return 4;
>    }
>}
>
>Or even: int f (int x) { return x ? 4 : 3; } or whatever...

Of course, but the question was not one of style, but one of legality.
The original code is legal and a conforming compiler must compile it. As
I said in my previous post, I like the warning that MSVC 6.0 gives, but
it should only be a warning.
---------------------------------------------------------------
Pablo Halpern                              phalpern@newview.org
Check out my new book, The C++ Standard Library from Scratch at
http://www.halpernwightsoftware.com/stdlib-scratch


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Michael Rubenstein <miker3@ix.netcom.com>
Date: 1999/12/07
Raw View
On 6 Dec 1999 19:25:05 GMT, Bennett McElwee
<bmcelwee@my-deja.com> wrote:

>However, in the case of
>
>> >> int f (int x)
>> >> {
>> >>     switch (x) {
>> >>     case 0:
>> >>         return 3;
>> >>     case 1:
>> >>         return 4;
>> >>     }
>> >> }
>
>the compiler can't generate code, because the function must always
>return some value. Perhaps it could just return an uninitialised
>value of the appropriate type; but what if the function was meant
>to return a reference? an uninitialised reference is completely
>useless.

The compiler must generate code unless it can be determined that
this function will be called with an argument other than 0 or 1.
There is no requirement in the standard that a function be able
to accept any possible input value.  This function will produce
undefined behavior if it is called with an argument other than 0
or 1, but if it is never called with such a value this code is
legal.  If your compiler does not compile the program

 int f (int x)
 {
   switch (x) {
     case 0:
       return 3;
     case 1:
       return 4;
   }
 }

it is broken.



[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: phalpern@newview.org (Pablo Halpern)
Date: 1999/12/07
Raw View
sirwillard@my-deja.com wrote:

>You are joking, right?  The possibility that any instruction, intended
>or not, could cocievably cause hardware to overheat and catch fire is
>the basis of an urban legend.  In other words, it's not very damn
>likely, and you'll be hard pressed to give a single documented
>occurrence of this having happened.  The idea that software can damage
>hardware in any way is far fetched.  The only thing not far fetched is
>that something unwanted may occur, such as formatting your hard drive,
>shutting the computer down hard stop, etc.

I once heard of a program that worked on an old mainframe (the kind
where each disk pack was the size of a stack of dishes and only held a
few MB). The program was written to cause the disk heads of multiple
drives to move in such a way as to cause a harmonic resonance making the
drives "walk" a few inches across the floor until the rammed into the
CPU cabinet. This could, of course, damage the hardware. It seems pretty
unlikely that this effect could be caused simply by a function executing
a path with no return value, though, so perhaps I'm getting a bit
off-topic.
---------------------------------------------------------------
Pablo Halpern                              phalpern@newview.org
Check out my new book, The C++ Standard Library from Scratch at
http://www.halpernwightsoftware.com/stdlib-scratch


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1999/12/07
Raw View
Jim Hyslop wrote:
>
> In article <3845C8BB.2083CEC5@cs.technion.ac.il>,
>   Yuri Tsoglin <tyuri@cs.technion.ac.il> wrote:
> [snip]
> > Maybe I know that x is either of the two (no matter how do I know)?
> > A better example could be:
> >
> >     enum color { red, yellow, green };
> >     color x;
> >     switch (x) {
> >         case red: return "R";
> >         case yellow: return "Y";
> >         case green: return "G";
> >     };

Well, actually this has undefined behaviour (reading from
undefined x), and indeed there's a good chance that x is
neither of the defined values ;-)

However:

enum color { red, yellow, green };

char* foo(color x)
{
  switch(x)
  {
    case red:    return "R";
    case yellow: return "Y";
    case green:  return "G";
  }
};

doesn't suffer from this problem.

> >
> > I understand that in general even here x can get a value which is
> > neither
> > red, yellow, nor green,
> > but if I know that in my specific program it will never happen, why
> > would I
> > write the "default" for it?
> For one, defensive programming.  Suppose the enum is defined in a header
> file, not in the same source file.  Suppose further that the function in
> which your code snippet appears must return a valid string no matter
> what value is passed to it.  Now suppose someone adds "purple" to the
> enums - guess what?  Your code just broke, and broke in such a way that
> its behaviour is now completely unpredictable.  Adding a
>    default: return "?";
>
> makes your function behave predictably no matter what happens to the
> enum.

Better:

     default: return NULL;

because this way an unchecked return value will most likely
be caught earlier by segfault, instead of causing hard to find
bugs due to values out of range.
If color should never have that value,

     default: assert (!"illegal value of color x in argument 1 of foo");

is probably a better solution, if ending the program is acceptable.
Otherwise the best solution IMHO is:

[...]

> > But if I am *absolutely* sure that there are no other cases, the only
> > reasonable thing I can do is to add:
> >
> >     default: throw SomeException();
> That's defensive programming again, but your compiler might still
> complain if it doesn't clue in to the fact that 'throw' terminates the
> function.  Your best bet, if you want to avoid all warnings, is to put
> in a return statement ;-)

But then, if the compiler _does_ know that throw ends the function,
it may warn about the unreachable return statement.

However: If you put the default case at the _beginning_, the
clueless compiler will think it's a fall-through to the next case,
and therefore not warn (since that next case has a return
statement).

So the absolute "warning-proof" version looks like:

enum color { red, yellow, green };

char* foo(color x)
{
  switch(x)
  {
    default:     throw EnumOutOfRange(x);
    case red:    return "R";
    case yellow: return "Y";
    case green:  return "G";
  }
}

>
> > Is the following function also incorrect, according to the standard?
> > int f ()
> > {
> >     switch (int x=1) {
> >         case 1:
> >             return 1;
> >     }
> > }
> > It seems very strange if it is.
> f() invokes "undefined behaviour" - but, since "undefined behaviour"
> means anything at all can happen, a compiler might replace that function
> with the equivalent of:
> int f()
> {
>    return 1;
> }

I'm not sure if a variable definition is allowed in switch,
but if it is allowed, f() has well-defined behaviour: x is
always 1, and therefore case 1 is always taken, and therefore
undefined behaviour (by falling over the end of the function)
does not occur. Therefore the compiler is not only allowed,
but required to compile this to be equivalent to
int f() { return 1; } (since it _is_ equivalent).


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1999/12/07
Raw View
"James Kuyper Jr." wrote:
>
> sirwillard@my-deja.com wrote:
> ....
> > You are joking, right?  The possibility that any instruction, intended
> > or not, could cocievably cause hardware to overheat and catch fire is
> > the basis of an urban legend.  In other words, it's not very damn
> > likely, and you'll be hard pressed to give a single documented
> > occurrence of this having happened. ...
>
> I never said it was likely, only possible. Furthermore, what a computer
> is capable of doing depends entirely upon what hardware is attached to
> it, which is something the standard says very little about. I think
> you'll agree that a computer which has control of a bomb attached to it
> could trivially blow itself up as a result of undefined behavior.

This reminds me of a real-world case (though not in C++):
The attached device was not a bomb, but an Ariane V...

[...]


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/12/01
Raw View
In article <3843E296.9068EB0D@cs.technion.ac.il>, Yuri Tsoglin
<tyuri@cs.technion.ac.il> writes
>2. This code:
>int f (int x)
>{
>    switch (x) {
>    case 0:
>        return 3;
>    case 1:
>        return 4;
>    }
>}
>
>gave error message in Visual C++ 5.0 and did not compile:
>'f' : not all control paths return a value

which is perfectly true, if x is neither 3 nor 4 what gets returned?

>In Visual C++ 6.0 it gives the same message but as warning (not error)
>and compiles!

All the standard requires is a diagnostic, having given such (and a
warning suffices) it can then do whatever it likes.  Perhaps the
behaviour of 6.0 would be preferred by those that like walking on the
edge of precipices.

>Which one does it correct?

Both:)


Francis Glassborow      Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Yuri Tsoglin <tyuri@cs.technion.ac.il>
Date: 1999/12/02
Raw View
Thanks.
BTW, your case is different:

> template <class T> class Bug2 {
>  public:
>     template<class U> void f (U u);  // f(U u) must be defined inline
>   // This won't compile successfully:
> template<class T> template<class U> Bug2<T>::f(U u)
> {
>         cout << "in template<class T> template<class U> Bug2<T>::f(U u) \n";
> }

This gives syntax error in compiler (not just linker error like in my
case).
And if I write it this way:

template<class T, class U> Bug2<T>::f(U u)
// note the difference
{
        cout << "in template<class T> template<class U> Bug2<T>::f(U u)\n";
}

or even if I make the class itself non-template, but still having
template member defined outside, it gives:

fatal error C1001: INTERNAL COMPILER ERROR

And I have encountered such message in some more cases, too.
The wonders of Microsoft ... :-)




[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1999/12/03
Raw View
Steve Clamage wrote:
>
> Yuri Tsoglin wrote:

[...]

> >
> > 2. This code:
> > int f (int x)
> > {
> >     switch (x) {
> >     case 0:
> >         return 3;
> >     case 1:
> >         return 4;
> >     }
> > }
> >
> > gave error message in Visual C++ 5.0 and did not compile:
> > 'f' : not all control paths return a value
> > In Visual C++ 6.0 it gives the same message but as warning (not error)
> > and compiles!
> > Which one does it correct?
> > In general, I looked at the standart, there is something like "undefined
> > behavior" in such cases.
> > What does "undefined behavior" mean: that a compiler should compile the
> > program but the run-time behavior is unknown,
> > or that a compiler may decide whether to compile it or not?
>
> If there is a control path that can "fall off the end" of the
> function without returning a value, the behavior of the program
> is undefined. The reason it is undefined is that in general it

[...]

> "Undefined behavior" is a technical term meaning that that standard
> places no requirements on the implementation.  "No requirements"
> means exactly that -- any behavior at all (refuse to compile, issue
> a warning, crash at run time, whatever) is allowed by the standard.
>
> The implementation can refuse to compile the code, issue messages
> at compile time, or at run time, or not do anything special. As a

[...]

Is an implementation really allowed to refuse to compile
this function?
I thought the undefined behaviour happens only if the path
is actually taken. So for the function f above, the compiler
would have to proof that this function is *ever* called with
a value of x other than 1 or 2, to legally refuse compiling.

Assume f is really intended to take a boolean value,
and only takes int to accomodate an interface that
cannot be changed. Then f would never be called with
anything other than 0 and 1, and the behaviour would
be well defined.


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: phalpern@newview.org (Pablo Halpern)
Date: 1999/12/03
Raw View
Steve Clamage <stephen.clamage@sun.com> wrote:

>
>Yuri Tsoglin wrote:
>>
>> 2. This code:
>> int f (int x)
>> {
>>     switch (x) {
>>     case 0:
>>         return 3;
>>     case 1:
>>         return 4;
>>     }
>> }
>>
>> gave error message in Visual C++ 5.0 and did not compile:
>> 'f' : not all control paths return a value
>> In Visual C++ 6.0 it gives the same message but as warning (not error)
>> and compiles!
>> Which one does it correct?
>
>If there is a control path that can "fall off the end" of the
>function without returning a value, the behavior of the program
>is undefined. The reason it is undefined is that in general it
>is impossible to know at compile time whether such a path exists.

If it is impossible to know at compile time, then how can the compiler
refuse to translate the code? It seems to me that unless the compiler
can prove (at compile time) that such a path *does* exist, then the
program is well-formed and undefined behavior cannot be diagnosed at
compile-time. Consider this code, for example:

 void g(int *p)
        {
   *p = 5;
 }

By your reasoning, can the compiler refuse to compile this becuase a
path might exist in the program where p will be a null or uninitialized
pointer? It is impossible for the compiler to know whether such a path
exists, so I'm sure most readers of this newsgroup would exist that a
conforming compiler *must* compile the above code *unless* it can prove
that there *is* a path that will cause p to be invalid. Using the same
logic, I would expect a conforming compiler *must* compile Yuri's code
*unless* it can prove that x will be other than 0 or 1 at runtime. In
fact, if f is called with a boolean expression argument (e.g. in
portable code that works with compilers that don't yet support bool),
you might be 100% certain that x is either 0 or 1.

I like the warning in VC 6.0, but I believe the error message is wrong.
---------------------------------------------------------------
Pablo Halpern                              phalpern@newview.org
Check out my new book, The C++ Standard Library from Scratch at
http://www.halpernwightsoftware.com/stdlib-scratch


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Yuri Tsoglin <tyuri@cs.technion.ac.il>
Date: 1999/11/30
Raw View
I have two questions:

1. In Visual C++ 6.0, the following code (all in one file!) does not
link:

template <class T>
class A {
public:
    class B {
    public:
        void g ();
    };
    void f ();
};

template <class T>
void A<T>::f () {}

template <class T>
void A<T>::B::g () {}

void main ()
{
 A<int> a;
 A<int>::B b;
 a.f();
 b.g();
}

and gives this error message:
unresolved external symbol "public: void __thiscall A<int>::B::g(void)"
But when I change it so that g() is defined within the class, it
succeeds, so there is no problem with A::f() defined outside..
It seems like incorrect behavior of the compiler (more exactly, of the
linker), isn't it?

2. This code:
int f (int x)
{
    switch (x) {
    case 0:
        return 3;
    case 1:
        return 4;
    }
}

gave error message in Visual C++ 5.0 and did not compile:
'f' : not all control paths return a value
In Visual C++ 6.0 it gives the same message but as warning (not error)
and compiles!
Which one does it correct?
In general, I looked at the standart, there is something like "undefined
behavior" in such cases.
What does "undefined behavior" mean: that a compiler should compile the
program but the run-time behavior is unknown,
or that a compiler may decide whether to compile it or not?



[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Steve Clamage <stephen.clamage@sun.com>
Date: 1999/11/30
Raw View
Yuri Tsoglin wrote:
>
> I have two questions:
>
> 1. In Visual C++ 6.0, the following code (all in one file!) does not
> link:
>
> template <class T>
> class A {
> public:
>     class B {
>     public:
>         void g ();
>     };
>     void f ();
> };
>
> template <class T>
> void A<T>::f () {}
>
> template <class T>
> void A<T>::B::g () {}
>
> void main ()
> {
>  A<int> a;
>  A<int>::B b;
>  a.f();
>  b.g();
> }
>
> and gives this error message:
> unresolved external symbol "public: void __thiscall A<int>::B::g(void)"
> But when I change it so that g() is defined within the class, it
> succeeds, so there is no problem with A::f() defined outside..
> It seems like incorrect behavior of the compiler (more exactly, of the
> linker), isn't it?

Except for "void main", which is illegal, your code is OK. (Funtion
"main" is required to have a return type of int.)  I believe VC++
has difficulty with template class member functions defined outside
the class.


>
> 2. This code:
> int f (int x)
> {
>     switch (x) {
>     case 0:
>         return 3;
>     case 1:
>         return 4;
>     }
> }
>
> gave error message in Visual C++ 5.0 and did not compile:
> 'f' : not all control paths return a value
> In Visual C++ 6.0 it gives the same message but as warning (not error)
> and compiles!
> Which one does it correct?
> In general, I looked at the standart, there is something like "undefined
> behavior" in such cases.
> What does "undefined behavior" mean: that a compiler should compile the
> program but the run-time behavior is unknown,
> or that a compiler may decide whether to compile it or not?

If there is a control path that can "fall off the end" of the
function without returning a value, the behavior of the program
is undefined. The reason it is undefined is that in general it
is impossible to know at compile time whether such a path exists.
 int g()
 {
  int k = 0;
  cin >> k;
  if( k > 0 )
   return k;
 }

"Undefined behavior" is a technical term meaning that that standard
places no requirements on the implementation.  "No requirements"
means exactly that -- any behavior at all (refuse to compile, issue
a warning, crash at run time, whatever) is allowed by the standard.

The implementation can refuse to compile the code, issue messages
at compile time, or at run time, or not do anything special. As a
customer of the compiler vendor you should expect something
reasonable, as opposed to your computer catching fire.

--
Steve Clamage, stephen.clamage@sun.com


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: James Kuyper <kuyper@wizard.net>
Date: 1999/11/30
Raw View
Steve Clamage wrote:
...
> "Undefined behavior" is a technical term meaning that that standard
> places no requirements on the implementation.  "No requirements"
> means exactly that -- any behavior at all (refuse to compile, issue
> a warning, crash at run time, whatever) is allowed by the standard.
>
> The implementation can refuse to compile the code, issue messages
> at compile time, or at run time, or not do anything special. As a
> customer of the compiler vendor you should expect something
> reasonable, as opposed to your computer catching fire.

Not true in general. Code which allows undefined behaviour could, in
general, have as one of its possible consequences the transmission to
any hardware attached to your computer any messages that hardware is
capable of recieving. It's quite possible that the messages sent could
put the hardware into a mode where it overheats and bursts into flame.
On high-end machines there are barriers to prevent this, but it's still
possible (though less likely) for defective code to find any holes that
might exist in those barriers. Defective code on modern machines can
execute billions of unintended instructions a second; I wouldn't be
willing to guarantee that such code will halt before executing a
dangerous instruction sequence.


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Kurt" <kkurt@ifsx.net>
Date: 1999/11/30
Raw View
> 1. In Visual C++ 6.0, the following code (all in one file!) does not
> link:
> template <class T>
> class A {
> public:
>     class B {
>     public:
>         void g ();
>     };
>     void f ();
> };

> template <class T>
> void A<T>::B::g () {}

> unresolved external symbol "public: void __thiscall A<int>::B::g(void)"
> But when I change it so that g() is defined within the class, it
> succeeds, so there is no problem with A::f() defined outside..

It is obvisouly a compiler bug.  You will find a similiar problem if you
have a template that contains template member functions:
 template <class T> class Bug2 {
 public:
    template<class U> void f (U u)  // f(U u) must be defined inline
    {
        cout << "in template<class T> template<class U> Bug2<T>::f(U u) \n";
    }
 };
// This won't compile successfully

template<class T> template<class U> Bug2<T>::f(U u)
{
        cout << "in template<class T> template<class U> Bug2<T>::f(U u) \n";
}
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: jcoffin@taeus.com (Jerry Coffin)
Date: 1999/12/01
Raw View
In article <3843E296.9068EB0D@cs.technion.ac.il>,
tyuri@cs.technion.ac.il says...
>
> I have two questions:
>
> 1. In Visual C++ 6.0, the following code (all in one file!) does not
> link:
>
> template <class T>
> class A {
> public:
>     class B {
>     public:
>         void g ();
>     };
>     void f ();
> };
>
> template <class T>
> void A<T>::f () {}
>
> template <class T>
> void A<T>::B::g () {}

Right -- VC++ doesn't handle this quite correctly.  If you move the
function definition into the class declaration:

> and gives this error message:
> unresolved external symbol "public: void __thiscall A<int>::B::g(void)"
> But when I change it so that g() is defined within the class, it
> succeeds, so there is no problem with A::f() defined outside..
> It seems like incorrect behavior of the compiler (more exactly, of the
> linker), isn't it?

Yes.  The truly strange part is that if you use "dumpbin /symbols" on
the object file, you'll find that it actually DOES contain exactly the
symbol that the linker says is unresolved...

[ ... ]

> What does "undefined behavior" mean: that a compiler should compile the
> program but the run-time behavior is unknown,
> or that a compiler may decide whether to compile it or not?

Undefined behavior means the compiler (or whatever other sort of
implementation you happen to run into) can do pretty much anything it
wants to.  It can treat it as an error, and refuse to accept the code
at all.  It can define what it'll do in this particular case, and
compile it to do something useful.  It can check with the attached GPS
system, figure out the phase of the moon, and based on that decide
whether to launch the thermonuclear devices you (hope you don't) have
attached to your serial port...

--
    Later,
    Jerry.

The universe is a figment of its own imagination.


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]