By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,421 Members | 1,128 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,421 IT Pros & Developers. It's quick & easy.

Why is this code valid C++?

P: n/a
Someone showed me something today that I didn't understand. This doesn't
seem like it should be valid C++. Specifically, I don't understand how the
commas are accepted after the function 'fprintf'. What effect do they have
in those parenthesis?

I understand how the or is useful and why never to do it, I'm really just
asking about that construction "(fprintf(stderr, "Can't open file.\n"),
exit(0), 1))".

---- CODE ----

#include <stdlib.h>
#include <stdio.h>

int main()
{
FILE *fp = (FILE *) (fopen("file","r") ||
(fprintf(stderr, "Can't open file.\n"), exit(0), 1));
return 0;
}

---- /CODE ----

- JFA1
Jul 23 '05 #1
Share this Question
Share on Google+
23 Replies


P: n/a
James Aguilar wrote:
Someone showed me something today that I didn't understand. This doesn't
seem like it should be valid C++. Specifically, I don't understand how the
commas are accepted after the function 'fprintf'. What effect do they have
in those parenthesis?

I understand how the or is useful and why never to do it, I'm really just
asking about that construction "(fprintf(stderr, "Can't open file.\n"),
exit(0), 1))".

---- CODE ----

#include <stdlib.h>
#include <stdio.h>

int main()
{
FILE *fp = (FILE *) (fopen("file","r") ||
(fprintf(stderr, "Can't open file.\n"), exit(0), 1));
return 0;
}

---- /CODE ----
...


This code is "valid" in a sense that it is "well-formed", i.e. it will
compile. It will compile simply because someone forced it to be
well-formed by introducing extra typecasts into otherwise completely
meaningless code. The code doesn't make any sense. It will not do
anything useful. Are you sure you reproduced it correctly?

I can only guess that the code was meant do look as follows

...
FILE *fp;
(fp = fopen("file","r")) ||
(fprintf(stderr, "Can't open file.\n"), exit(0), 1));
...

This will "work". In short, if the 'fopen' succeeds, the program will
not try to evaluate the second operand of '||' operator and the whole
thing will be equivalent to 'fp = fopen("file","r")'.

If 'fopen' fails (i.e. returns NULL), the program will proceed to
evaluating the second operand of '||' expression: print the error
message and terminate.

Read more about the properties of built-in '||' operator and comma (',')
operator for more details. I believe, you can find some useful
information in the FAQ.

--
Best regards,
Andrey Tarasevich
Jul 23 '05 #2

P: n/a
"James Aguilar" <jf**@cec.wustl.edu> wrote in message
news:cu**********@newsreader.wustl.edu...
Someone showed me something today that I didn't understand. This doesn't seem like it should be valid C++. Specifically, I don't
understand how the commas are accepted after the function 'fprintf'. What
effect do they have in those parenthesis? When not used to separate parameters, within an expression, the comma
acts as a sequence operator: it evaluates the expression on its left,
then the expression on its right, and returns the result of the latter.
For example:
int x = (3,5); // initializes x with '5'
In practice, the use of the comma operator is (&should be) rare in C++.
I understand how the or is useful and why never to do it, I'm really just
asking about that construction "(fprintf(stderr, "Can't open file.\n"),
exit(0), 1))".
Yes, this code looks like someone trying to write Perl in C++ - which
doesn't make sense and fails because of stronger typing and different
operator semantics.
FILE *fp = (FILE *) (fopen("file","r") ||
(fprintf(stderr, "Can't open file.\n"), exit(0), 1));


In Perl, the || operator returns its left-side expression if it is
non-zero. In C++, it returns a bool, so although the code compiles,
fp will be initialized with (FILE*)1 - which will lead to undefined
behavior if it is used.
Such code would not even have its place in an obfuscated C code contest,
because it doesn't even work, and "leaks" a file handle.

The ",1" is needed so that the result of the ...,exit(0),1 expression
will be an integer, compatible with the || operator.
( exit(0) has a void return type, and would be an error).
--
http://ivan.vecerina.com/contact/?subject=NG_POST <- email contact form


Jul 23 '05 #3

P: n/a
James Aguilar wrote:

#include <stdlib.h>
#include <stdio.h>

int main()
{
FILE *fp = (FILE *) (fopen("file","r") ||
(fprintf(stderr, "Can't open file.\n"), exit(0), 1));
return 0;
}


This actually belongs on comp.lang.c, there is no C++ specific code
here, but...

If you look, the entire boolean expression is in parens. So if fopen
succeeds, the || statement short-circuits, returning the file pointer,
which is cast into a FILE* and assigned to fp.

If the fopen fails, it returns NULL (or 0), which causes the second part
of the || to evaluate. It uses the "," operator, which returns the
value of it's RHS. So, it does fprintf [returns int], exit ["returns"
void] and 1 [int]). Note that the expression 1 will never be evaluated,
but the compiler needs it to be happy, since a void cannot be cast to a
FILE*.

The original coder was trying to be clever and "efficient", but I
suspect that the code for this is no more efficient that the much more
readable:

#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE* fp = fopen("file", "r");
if (fp == NULL)
{
fprintf(stderr, "Can't open file.\n");
exit(EXIT_FAILURE);
}
return EXIT_SUCCESS;
}
Jul 23 '05 #4

P: n/a
One more thing I never knew. Thank you very much.

- JFA1
Jul 23 '05 #5

P: n/a
James Aguilar wrote:
Someone showed me something today that I didn't understand. This doesn't
seem like it should be valid C++. Specifically, I don't understand how the
commas are accepted after the function 'fprintf'. What effect do they have
in those parenthesis?
'exit(0)' is executed. 1 is just for syntactic and semantic correctness,
since the right operand of || has to have a value and 'exit' doesn't
return any.

I understand how the or is useful and why never to do it, I'm really just
asking about that construction "(fprintf(stderr, "Can't open file.\n"),
exit(0), 1))".

---- CODE ----

#include <stdlib.h>
#include <stdio.h>

int main()
{
FILE *fp = (FILE *) (fopen("file","r") ||
(fprintf(stderr, "Can't open file.\n"), exit(0), 1));
return 0;
}

---- /CODE ----


It's not valid C++. It's valid C90. But it's very close to being valid
C++, though.

The || operator causes the evaluation of the left operand. If the result
of that evaluation is not zero (and in this case if 'fopen' returns a non-
null pointer), the evaluation stops. HOWEVER, 'fp' may simply get a wrong
value. Once the left side of || is non-zero, it _may_ be converted (and
should be converted) to a bool value, which is 'true'. After that the
same 'true' is cast back to (FILE*), which causes undefined behaviour.

If the call to 'fopen' returns NULL, then the right side of || is then
evaluated. The code has a parenthesized expression with three separate
subexpressions connected by two operator comma. There is a sequence point
at every comma, so first 'fprintf' is executed. It supposedly prints out
the error message. Then 'exit(0)' is executed. That forces the end of
the program. The '1' after that is not really needed, but is there to
probably satisfy the need to have a value as the result of evaluating the
parenthesized right-hand side of the || operator.

Since if 'fopen' fails to open the file, the 1 is never cast to FILE* and
'fp' is never assigned that value, there is no concern for undefined
behaviour which should happen otherwise because casting an integer to
a pointer is not defined unless the integer itself what obtained by the
symmetrical cast *from* a pointer before.

So, as you can see, the only problem here is when it actually _can_ open
the file.

V
Jul 23 '05 #6

P: n/a
red floyd wrote:

#include <stdlib.h>
#include <stdio.h>

int main()
{
FILE *fp = (FILE *) (fopen("file","r") ||
(fprintf(stderr, "Can't open file.\n"), exit(0), 1));
return 0;
}


This actually belongs on comp.lang.c, there is no C++ specific code
here, but...

If you look, the entire boolean expression is in parens. So if fopen
succeeds, the || statement short-circuits, returning the file pointer,
which is cast into a FILE* and assigned to fp.


No, even if it short-circuits, it will not return file pointer. Boolean
expressions (as this one) return only 'true' or 'false', nothing else.
When 'fopen' succeeds and this '||' expression short-circuits, it
returns 'true' which is then cast to 'FILE*' type and stored in 'fp'.
Casting 'true' to 'FILE*' type doesn't make any sense.

This obfuscated technique can be applied properly (see my another
message), but the above is not it.

--
Best regards,
Andrey Tarasevich
Jul 23 '05 #7

P: n/a
James Aguilar wrote:
Someone showed me something today that I didn't understand.
This doesn't seem like it should be valid C++. Specifically,
I don't understand how the commas are accepted after the function 'fprintf'.
What effect do they have in those parenthesis?

I understand how the or is useful and why never to do it.
I'm really just asking about that construction
"(fprintf(stderr, "Can't open file.\n"), exit(0), 1))".

---- CODE ----

#include <stdlib.h>
#include <stdio.h>

int main(int argc, char* argv[]) {
FILE *fp = (FILE *) (fopen("file","r")
|| (fprintf(stderr, "Can't open file.\n"), exit(0), 1));
return 0;
}

---- /CODE ----


It means the same thing as:

#include <stdlib.h>
#include <stdio.h>

int main(int argc, char* argv[]) {
FILE* fp = fopen("file", "r");
if (NULL == fp) {
fprintf(stderr, "Can't open file.\n");
exit(EXIT_SUCCESS);
}
return EXIT_SUCCESS;
}
A comma separated list of expressions

(expression1, expression2, . . ., expressionN)

are evaluated in order and has the value of the last expression.
Jul 23 '05 #8

P: n/a
E. Robert Tisdale wrote:

---- CODE ----

#include <stdlib.h>
#include <stdio.h>

int main(int argc, char* argv[]) {
FILE *fp = (FILE *) (fopen("file","r")
|| (fprintf(stderr, "Can't open file.\n"), exit(0), 1));
return 0;
}

---- /CODE ----


It means the same thing as:

#include <stdlib.h>
#include <stdio.h>

int main(int argc, char* argv[]) {
FILE* fp = fopen("file", "r");
if (NULL == fp) {
fprintf(stderr, "Can't open file.\n");
exit(EXIT_SUCCESS);
}
return EXIT_SUCCESS;
}
...


No, it doesn't. It means the same thing as

FILE* fp;
if (fopen("file", "r") != NULL)
fp = (FILE*) true;
else
{
fprintf(stderr, "Can't open file.\n");
exit(EXIT_SUCCESS);
}

Do you notice the difference?

--
Best regards,
Andrey Tarasevich
Jul 23 '05 #9

P: n/a
In fact, printf and scanf are implemented as functions. What you see is the
standard c++ function style. But I still don't understand why some people
use it.

"James Aguilar" <jf**@cec.wustl.edu> дʼ
news:cu**********@newsreader.wustl.edu...
Someone showed me something today that I didn't understand. This doesn't
seem like it should be valid C++. Specifically, I don't understand how the commas are accepted after the function 'fprintf'. What effect do they have in those parenthesis?

I understand how the or is useful and why never to do it, I'm really just
asking about that construction "(fprintf(stderr, "Can't open file.\n"),
exit(0), 1))".

---- CODE ----

#include <stdlib.h>
#include <stdio.h>

int main()
{
FILE *fp = (FILE *) (fopen("file","r") ||
(fprintf(stderr, "Can't open file.\n"), exit(0), 1));
return 0;
}

---- /CODE ----

- JFA1

Jul 23 '05 #10

P: n/a
Andrey Tarasevich wrote:
E. Robert Tisdale wrote:
James Aguilar wrote:
---- CODE ----

#include <stdlib.h>
#include <stdio.h>

int main(int argc, char* argv[]) {
FILE *fp = (FILE *) (fopen("file","r")
|| (fprintf(stderr, "Can't open file.\n"), exit(0), 1));
return 0;
}

---- /CODE ----


It means the same thing as:

#include <stdlib.h>
#include <stdio.h>

int main(int argc, char* argv[]) {
FILE* fp = fopen("file", "r");
if (NULL == fp) {
fprintf(stderr, "Can't open file.\n");
exit(EXIT_SUCCESS);
}
return EXIT_SUCCESS;
}


No, it doesn't. It means the same thing as

FILE* fp;
if (fopen("file", "r") != NULL)
fp = (FILE*) true;
else
{
fprintf(stderr, "Can't open file.\n");
exit(EXIT_SUCCESS);
}

Do you notice the difference?


It depends upon whether you think that
it is a C program or a C++ program.

I think that James Aguilar posted a C program
to the comp.lang.c++ newsgroup [by mistake].
Jul 23 '05 #11

P: n/a
"E. Robert Tisdale" <E.**************@jpl.nasa.gov> wrote in message
news:cu**********@nntp1.jpl.nasa.gov...
It depends upon whether you think that
it is a C program or a C++ program.

I think that James Aguilar posted a C program
to the comp.lang.c++ newsgroup [by mistake].


Could be. I thought that C-language was a subset of C++-language, but I
heard there were some differences. Is this one?

-JFA1
Jul 23 '05 #12

P: n/a
E. Robert Tisdale wrote:

No, it doesn't. It means the same thing as

FILE* fp;
if (fopen("file", "r") != NULL)
fp = (FILE*) true;
else
{
fprintf(stderr, "Can't open file.\n");
exit(EXIT_SUCCESS);
}

Do you notice the difference?


It depends upon whether you think that
it is a C program or a C++ program.

I think that James Aguilar posted a C program
to the comp.lang.c++ newsgroup [by mistake].


It doesn't make any difference. In C language logical operators evaluate
to either integral 0 or 1. In C it would be equivalent to

FILE* fp;
if (fopen("file", "r") != NULL)
fp = (FILE*) 1;
else
{
fprintf(stderr, "Can't open file.\n");
exit(EXIT_SUCCESS);
}

Converting integral '1' to 'FILE*' type doesn't make any more sense than
converting 'true' to the same type. The code is meaningless in both C
and C++ in virtually the same way.

--
Best regards,
Andrey Tarasevich
Jul 23 '05 #13

P: n/a
James Aguilar wrote:
[...] I thought that C-language was a subset of C++-language, but I
heard there were some differences. Is this one?


You thought incorrectly. You heard correctly. Yes, this is one.
C is still handling || as if both operands are of "scalar" type and
simply compares them to 0. In C++ both operands are converted to type
'bool' (although the second is not really evaluated or converted if
the first one evaluates to true).

V
Jul 23 '05 #14

P: n/a
In article <cu**********@newsreader.wustl.edu>,
James Aguilar <jf**@cec.wustl.edu> wrote:
"E. Robert Tisdale" <E.**************@jpl.nasa.gov> wrote in message
news:cu**********@nntp1.jpl.nasa.gov...
It depends upon whether you think that
it is a C program or a C++ program.

I think that James Aguilar posted a C program
to the comp.lang.c++ newsgroup [by mistake].


Could be. I thought that C-language was a subset of C++-language, but I
heard there were some differences. Is this one?


There are constructs that are valid C and not valid C++, and constructs
that are valid in both languages but have different meanings, and these
constructs tend to show up in most nontrivial C code, so C is not a
subset of C++.

The code you posted was, as far as I saw (I didn't look too closely),
in the common subset of the two languages (that is, it was valid-ish
and had the same meaning in both), though.
dave
(int *old=malloc(sizeof *old),*new=malloc(sizeof *new);)

--
Dave Vandervies dj******@csclub.uwaterloo.ca
My personal best estimate is that 90% of existing C code is crap (F various VO
crap), and 90% of existing NotC code is crap too. (I expect this to be true of
non-existing code as well.) --Dimitri Mazuik in the scary devil monastery
Jul 23 '05 #15

P: n/a
Victor Bazarov wrote:
[..]
It's not valid C++. It's valid C90. [...]


My bad. It's not valid C90 either. I trust Andrey's
memory, I don't have a copy of C90 Standard any more.
Jul 23 '05 #16

P: n/a
Victor Bazarov wrote:
[...] I thought that C-language was a subset of C++-language, but I
heard there were some differences. Is this one?


You thought incorrectly. You heard correctly. Yes, this is one.
C is still handling || as if both operands are of "scalar" type and
simply compares them to 0. In C++ both operands are converted to type
'bool' (although the second is not really evaluated or converted if
the first one evaluates to true).


This doesn't mean though that '||' in C will preserve the
non-zero-operand and return its value as the result. In C '||' always
returns '0' or '1', which corresponds to 'true' or 'false' in C++. For
the original piece of code it is not a critical difference. It is as
broken in C, as it is in C++.

--
Best regards,
Andrey Tarasevich
Jul 23 '05 #17

P: n/a
In article <vM*******************@newsread1.mlpsca01.us.to.ve rio.net>,
Victor Bazarov <v.********@comAcast.net> wrote:
C is still handling || as if both operands are of "scalar" type and
simply compares them to 0. In C++ both operands are converted to type
'bool' (although the second is not really evaluated or converted if
the first one evaluates to true).


Are there any cases where comparison to 0 and conversion to bool will
give different results? It seems to me that the C++ definitions of
conversions to and from bool don't allow the result to ever be different
from the C definition of compare-to-0.
dave

--
Dave Vandervies dj******@csclub.uwaterloo.ca
My personal best estimate is that 90% of existing C code is crap (F various VO
crap), and 90% of existing NotC code is crap too. (I expect this to be true of
non-existing code as well.) --Dimitri Mazuik in the scary devil monastery
Jul 23 '05 #18

P: n/a
Dave Vandervies wrote:
In article <vM*******************@newsread1.mlpsca01.us.to.ve rio.net>,
Victor Bazarov <v.********@comAcast.net> wrote:

C is still handling || as if both operands are of "scalar" type and
simply compares them to 0. In C++ both operands are converted to type
'bool' (although the second is not really evaluated or converted if
the first one evaluates to true).

Are there any cases where comparison to 0 and conversion to bool will
give different results? It seems to me that the C++ definitions of
conversions to and from bool don't allow the result to ever be different
from the C definition of compare-to-0.


There probably isn't, as far as "scalar" types are concerned, and since C
doesn't have overloaded operators (at least yet), there is no fear about
'conversion to bool' conflicting with 'comparison to 0', which in C++
can easily give different results but only for UDTs.

V
Jul 23 '05 #19

P: n/a
On Thu, 10 Feb 2005 17:38:13 -0500, Victor Bazarov
<v.********@comAcast.net> wrote in comp.lang.c++:
James Aguilar wrote:
Someone showed me something today that I didn't understand. This doesn't
seem like it should be valid C++. Specifically, I don't understand how the
commas are accepted after the function 'fprintf'. What effect do they have
in those parenthesis?


'exit(0)' is executed. 1 is just for syntactic and semantic correctness,
since the right operand of || has to have a value and 'exit' doesn't
return any.

I understand how the or is useful and why never to do it, I'm really just
asking about that construction "(fprintf(stderr, "Can't open file.\n"),
exit(0), 1))".

---- CODE ----

#include <stdlib.h>
#include <stdio.h>

int main()
{
FILE *fp = (FILE *) (fopen("file","r") ||
(fprintf(stderr, "Can't open file.\n"), exit(0), 1));
return 0;
}

---- /CODE ----


It's not valid C++. It's valid C90. But it's very close to being valid
C++, though.

The || operator causes the evaluation of the left operand. If the result
of that evaluation is not zero (and in this case if 'fopen' returns a non-
null pointer), the evaluation stops. HOWEVER, 'fp' may simply get a wrong
value. Once the left side of || is non-zero, it _may_ be converted (and
should be converted) to a bool value, which is 'true'. After that the
same 'true' is cast back to (FILE*), which causes undefined behaviour.


No, it does not, this conversion is well defined.

3.9.1 Fundamental types P7: "Types bool, char, wchar_t, and the signed
and unsigned integer types are collectively called integral types."

5.2.10 Reinterpret cast P5: "A value of integral type or enumeration
type can be explicitly converted to a pointer."

And 5.4 Explicit type conversion (cast notation) makes it quite clear
that the C-style case can perform any valid conversions that any C++
cast can.

So the explicit cast of the value 1 or true is valid in either C or
C++, regardless of whether that value has the type bool (C++), int
(C90), or _bool (C99).

The C++ standard in 5.2.10 P5 includes the clause "mappings between
pointers and integers are otherwise implementation-defined.", while I
prefer the C standard's stronger disclaimer:

========
An integer may be converted to any pointer type. Except as previously
specified, the result is implementation-defined, might not be
correctly aligned, might not point to an entity of the referenced
type, and might be a trap representation.
========

In any case, the conversion to pointer is not undefined, but any
attempt to dereference the resulting pointer most certainly is.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Jul 23 '05 #20

P: n/a
Andrey Tarasevich wrote:
red floyd wrote:
#include <stdlib.h>
#include <stdio.h>

int main()
{
FILE *fp = (FILE *) (fopen("file","r") ||
(fprintf(stderr, "Can't open file.\n"), exit(0), 1));
return 0;
}


This actually belongs on comp.lang.c, there is no C++ specific code
here, but...

If you look, the entire boolean expression is in parens. So if fopen
succeeds, the || statement short-circuits, returning the file pointer,
which is cast into a FILE* and assigned to fp.

No, even if it short-circuits, it will not return file pointer. Boolean
expressions (as this one) return only 'true' or 'false', nothing else.
When 'fopen' succeeds and this '||' expression short-circuits, it
returns 'true' which is then cast to 'FILE*' type and stored in 'fp'.
Casting 'true' to 'FILE*' type doesn't make any sense.

This obfuscated technique can be applied properly (see my another
message), but the above is not it.


You're right. I misread the code.
Jul 23 '05 #21

P: n/a
Jack Klein wrote:
[...]
In any case, the conversion to pointer is not undefined, but any
attempt to dereference the resulting pointer most certainly is.


It has been discussed several times (that I can remember) that on
some architectures even assigning an invalid value to a pointer may
result in a hardware fault. I don't want to begin that discussion
again.

V
Jul 23 '05 #22

P: n/a
On Fri, 11 Feb 2005 09:46:32 -0500, Victor Bazarov
<v.********@comAcast.net> wrote in comp.lang.c++:
Jack Klein wrote:
[...]
In any case, the conversion to pointer is not undefined, but any
attempt to dereference the resulting pointer most certainly is.


It has been discussed several times (that I can remember) that on
some architectures even assigning an invalid value to a pointer may
result in a hardware fault. I don't want to begin that discussion
again.

V


Then the C++ compiler must do something to prevent the hardware from
generating an exception when an integer type is converted to a
pointer. It may be an invalid pointer, but it may not generate
undefined behavior unless used. If it allows undefined behavior, the
compiler is non-conforming.

The standard specifically states that the conversion is allowed, with
the mapping being implementation-defined.

Any compiler that generates undefined behavior for an operation that
the standard says is implementation-defined is non-conforming.
Undefined behavior is never a conforming option for
implementation-defined behavior.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Jul 23 '05 #23

P: n/a
Jack Klein wrote:

[ ... ]
Then the C++ compiler must do something to prevent the hardware from
generating an exception when an integer type is converted to a
pointer. It may be an invalid pointer, but it may not generate
undefined behavior unless used. If it allows undefined behavior, the
compiler is non-conforming.

The standard specifically states that the conversion is allowed, with
the mapping being implementation-defined.

Any compiler that generates undefined behavior for an operation that
the standard says is implementation-defined is non-conforming.
Undefined behavior is never a conforming option for
implementation-defined behavior.


Implementation defined behavior is defined only as "Behavior ... that
depends on the implementation and that each implementation shall
document."

As such, the difference between undefined behavior and implementation
defined behavior is substantially smaller than you imply above. The
range of possible responses to each is similar. The real difference is
that implementation defined behavior must be documented, where
undefined behavior does not.

If, however, if the implementation documents that "Attempting to
convert an integer to a pointer may throw an exception.", the
requirements of the standard seem to have been met.

It's open to question that there is a slight difference in the
requirements on the behavior, inasmuch as undefined behavior may give
results that are unpredictable to a degree that documenting them is
essentially impossible, whereas implementation defined behavior must
give results that are documented, and therefore must be predictable
enough to BE documented. The question involved is whether "something
totally unpredictable may happen." would qualify as having documented
the behavior -- some say it is, but I tend to disagree. Regardless of
that, however, I see absolutely NO requirement in the standard that
rules out throwing an exception as implementation defined behavior.

--
Later,
Jerry.

The universe is a figment of its own imagination.

Jul 23 '05 #24

This discussion thread is closed

Replies have been disabled for this discussion.