473,396 Members | 1,599 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

return (i = 1, NULL)

is this legal:

FILE *func(void) {
extern int errno;

return (errno = EINVAL, NULL);
}

my compiler (gcc 2.9.x on openbsd) is complaining that i'm returning a
pointer from int w/o a cast. gcc 3.x on linux, however, never made a peep
about it, so possibly 2.9.x is just grumpy.

i suppose the relevent question is, can one group different types like
that?

tia,

Bill
Nov 13 '05 #1
14 2681
Ben Pfaff <bl*@cs.stanford.edu> wrote:
William Ahern <wi*****@wilbur.25thandClement.com> writes:
is this legal:

FILE *func(void) {
extern int errno;

return (errno = EINVAL, NULL);
}

No. You can't declare `errno' yourself like that (it's not
necessarily a variable) and you forgot to #include <stdio.h>. If you fix those two problems, then yes.
yes. yeah.*
If you fix those two problems, then yes.


that's what i thought. thanx.

- Bill

* - http://www.ebaumsworld.com/arnolds3.html

Nov 13 '05 #2

"William Ahern" <wi*****@wilbur.25thandClement.com> wrote in message news:36************@wilbur.25thandClement.com...
is this legal:

FILE *func(void) {
extern int errno;

return (errno = EINVAL, NULL);
}

my compiler (gcc 2.9.x on openbsd) is complaining that i'm returning a
pointer from int w/o a cast. gcc 3.x on linux, however, never made a peep
about it, so possibly 2.9.x is just grumpy.


To avoid the discussion on the name space pollution, let me rewrite
your code:

FILE *func(void)
{
extern int my_errno;

return (my_errno = SOME_VALUE, NULL);
}

And the expression given to the return statement is not a constant
expression, becuase it contains the comma operator. Therefore, in the
*full* expression for the return, NULL doesn't qualify as a null
pointer constant. If your implementation #defines NULL simply as 0 (or
similar ones whose types are not assignment-compatible with FILE *),
your program is illegal, which is what gcc complains about.
--
Jun, Woong (my******@hanmail.net)
Nov 13 '05 #3
William Ahern <wi*****@wilbur.25thandClement.com> wrote in message news:<36************@wilbur.25thandClement.com>...
is this legal:

FILE *func(void) {
extern int errno;

return (errno = EINVAL, NULL);
}

my compiler (gcc 2.9.x on openbsd) is complaining that i'm returning a
pointer from int w/o a cast. gcc 3.x on linux, however, never made a peep
about it, so possibly 2.9.x is just grumpy.


Compiler bug. The return statement does not require ( ), incidentally.

Sam
Nov 13 '05 #4
On 25 Aug 2003 01:02:48 -0700, Samuel Barber <op*****@yahoo.com> wrote:
William Ahern <wi*****@wilbur.25thandClement.com> wrote in message
news:<36************@wilbur.25thandClement.com>...
is this legal:

FILE *func(void) {
extern int errno;

return (errno = EINVAL, NULL);
}

my compiler (gcc 2.9.x on openbsd) is complaining that i'm returning a
pointer from int w/o a cast. gcc 3.x on linux, however, never made a peep
about it, so possibly 2.9.x is just grumpy.


Compiler bug. The return statement does not require ( ), incidentally.


It's not a compiler bug. On FreeBSD, and thus I assume OpenBSD, NULL is
an unadorned zero:
#define NULL 0

On Linux, it's
#define NULL ((void*)0)

Both are legal definitions of NULL. However, in some circumstances the
differences can bite you. This is one of those.

Since the function is defined as returning a pointer, you should return
a pointer (surprise). The issue here is what, exactly, a null pointer
is.

A plain old zero is allowed to be a null pointer, given the proper
context. One of the constraints is that it must be a constant
expression, and the comma operator is not allowed in a constant
expression.

So, assuming NULL is just zero, we have something like:
return (errno = EINVAL, 0);

The value that's being returned has type integer, and is zero. But
it's not a constant expression, and thus converting it to a pointer type
isn't going to create a null pointer (or rather, it might or might not
depending on your implementation, but it's safer to assume it won't.)

However, if NULL is ((void*)0), then it's:
return (errno = EINVAL, ((void*)0));

The value being returned here has type void*, and is a null pointer. It
is not a constant expression, but that's OK, because a constant
expression is only required to convert an integer zero to a null
pointer, not to convert a null pointer to another pointer type.

This is a very confusing part of C, but it does show why you should
always pretend NULL is just a plain old zero. In fact, some people
refuse to use NULL at all because of issues like this; instead, they
just use a zero as a null pointer. I like NULL, personally, because I
know when to cast it and using NULL just makes the code a bit more self
documenting, IMO.

To be complete, the proper fix for the above code is:
return (errno = EINVAL, (void*)NULL);
or
return (errno = EINVAL, (void*)0);
or
... something that doesn't use the comma operator!

Chris
Nov 13 '05 #5
Chris Spiegel <us*************@happyjack.org> wrote in message news:<sl********************@midgard.spiegels>...
A plain old zero is allowed to be a null pointer, given the proper
context. One of the constraints is that it must be a constant
expression, and the comma operator is not allowed in a constant
expression.

So, assuming NULL is just zero, we have something like:
return (errno = EINVAL, 0);

The value that's being returned has type integer, and is zero. But
it's not a constant expression, and thus converting it to a pointer type
isn't going to create a null pointer (or rather, it might or might not
depending on your implementation, but it's safer to assume it won't.)

However, if NULL is ((void*)0), then it's:
return (errno = EINVAL, ((void*)0));

The value being returned here has type void*, and is a null pointer. It
is not a constant expression, but that's OK, because a constant
expression is only required to convert an integer zero to a null
pointer, not to convert a null pointer to another pointer type.
Thank you for the correction.
To be complete, the proper fix for the above code is:
return (errno = EINVAL, (void*)NULL);
or
return (errno = EINVAL, (void*)0);
or
.. something that doesn't use the comma operator!


The last is by far the best fix, most importantly because (void*)0 is
not portable to C++.

Sam
Nov 13 '05 #6
Samuel Barber <op*****@yahoo.com> wrote:
Chris Spiegel <us*************@happyjack.org> wrote in message news:<sl********************@midgard.spiegels>...

<snip>
To be complete, the proper fix for the above code is:
return (errno = EINVAL, (void*)NULL);
or
return (errno = EINVAL, (void*)0);
or
.. something that doesn't use the comma operator!


The last is by far the best fix, most importantly because (void*)0 is
not portable to C++.

Sam


I liked the comma form because of its expressiveness. I've used it
exclusively w/ setting errno in a bunch of code (tho, this was the only
instance where I was returning a pointer rather than an int). In these cases
you really are returning two values, and it makes the code much more
readable w/o the additional braces since I love to do a lot of sanity
checking (since I never know where I might copy+paste the code).

But, I'll be mindful of the pitfalls. Thanks Chris for the great
explanation.

- Bill

Nov 13 '05 #7
op*****@yahoo.com (Samuel Barber) writes:
The last is by far the best fix, most importantly because (void*)0 is
not portable to C++.


When writing C code, there is no reason to worry about what C++
compilers will think of it. (Header files are a possible
exception.)
--
"The expression isn't unclear *at all* and only an expert could actually
have doubts about it"
--Dan Pop
Nov 13 '05 #8
>> return (my_errno = SOME_VALUE, NULL);
Why not:

my_errno = SOME_VALUE; return NULL;

--
#include <standard.disclaimer>
_
Kevin D Quitt USA 91387-4454 96.37% of all statistics are made up
Per the FCA, this address may not be added to any commercial mail list
Nov 13 '05 #9
Kevin D. Quitt <KQ****@ieeinc.com> wrote:
return (my_errno = SOME_VALUE, NULL);

Why not:

my_errno = SOME_VALUE; return NULL;


Because I usually use brevity and clarity like so:

if (check_parameter)
return (errno = EINVAL, NULL);

Tho, this was the first time I had to return a null pointer rather
than another error identifer like -1.

The alterntives are:

if (some_condition) {
errno = EINVAL;
return NULL;
}

[three or four more time]

or

if (some_condition1 || some_condition2 || some_condition3 || ...) {
errno = (some_condition)? ENAMETOOLONG : EINVAL
return NULL;
}

Neither of those are very satisfactory for code that isn't even central
to the purpose of the function.
Nov 13 '05 #10

On Tue, 26 Aug 2003, William Ahern wrote:

Kevin D. Quitt <KQ****@ieeinc.com> wrote:
return (my_errno = SOME_VALUE, NULL);
Why not:

my_errno = SOME_VALUE; return NULL;


Because I usually use brevity and clarity like so:

if (check_parameter)
return (errno = EINVAL, NULL);

Tho, this was the first time I had to return a null pointer rather
than another error identifer like -1.

The alternatives are:

if (some_condition) {
errno = EINVAL;
return NULL;
}

or

if (some_condition1 || some_condition2 || some_condition3 || ...) {
errno = (some_condition)? ENAMETOOLONG : EINVAL
return NULL;
}


I think the simplest solution has been determined to be:

if (some_condition)
return (errno = EINVAL, (void *) NULL);

Still, I agree that this is almost certainly obfuscation. Have
you considered my /idiom du jour/,

if (some_condition1)
goto exit_failure1;
if (some_condition2)
goto exit_failure2;
...

exit_failure1:
errno = EINVAL;
return NULL;

exit_failure2:
errno = ENAMETOOLONG;
return NULL;
Very compact, and has the added bonus that all the "exit" code is in
one place. That means it's harder to miss a free(), and easier to
figure out all the possible return codes (which should be documented
anyway, of course, but still..).

HTH,
-Arthur

Nov 13 '05 #11
Ben Pfaff <bl*@cs.stanford.edu> wrote in message news:<87************@pfaff.stanford.edu>...
op*****@yahoo.com (Samuel Barber) writes:
The last is by far the best fix, most importantly because (void*)0 is
not portable to C++.


When writing C code, there is no reason to worry about what C++
compilers will think of it. (Header files are a possible
exception.)


C code is not neccessarily bad if it's not C++-compatible, but
C++-compatibility is certainly a valid point when considering the
merits of a C code fragment in the abstract. There are many reasons to
prefer C++ compatibility, all things being equal.

Sam
Nov 13 '05 #12
In article <37**************************@posting.google.com >,
Samuel Barber <op*****@yahoo.com> wrote:
Ben Pfaff <bl*@cs.stanford.edu> wrote in message news:<87************@pfaff.stanford.edu>...
op*****@yahoo.com (Samuel Barber) writes:
> The last is by far the best fix, most importantly because (void*)0 is
> not portable to C++.


When writing C code, there is no reason to worry about what C++
compilers will think of it. (Header files are a possible
exception.)


C code is not neccessarily bad if it's not C++-compatible, but
C++-compatibility is certainly a valid point when considering the
merits of a C code fragment in the abstract. There are many reasons to
prefer C++ compatibility, all things being equal.


I think Sam has a reasonable point. Of course, it need not
always be the case, but clearly many C programmers
do -- and should -- worry about what C++ compilers will think.
--
Greg Comeau/4.3.3:Full C++03 core language + more Windows backends
Comeau C/C++ ONLINE ==> http://www.comeaucomputing.com/tryitout
World Class Compilers: Breathtaking C++, Amazing C99, Fabulous C90.
Comeau C/C++ with Dinkumware's Libraries... Have you tried it?
Nov 13 '05 #13
In article <ne********************@tomato.pcug.org.au>,
Kevin Easton <kevin@-nospam-pcug.org.au> wrote:
Greg Comeau <co****@panix.com> wrote:
In article <37**************************@posting.google.com >,
Samuel Barber <op*****@yahoo.com> wrote:
Ben Pfaff <bl*@cs.stanford.edu> wrote in message news:<87************@pfaff.stanford.edu>...
op*****@yahoo.com (Samuel Barber) writes:

> The last is by far the best fix, most importantly because (void*)0 is
> not portable to C++.

When writing C code, there is no reason to worry about what C++
compilers will think of it. (Header files are a possible
exception.)

C code is not neccessarily bad if it's not C++-compatible, but
C++-compatibility is certainly a valid point when considering the
merits of a C code fragment in the abstract. There are many reasons to
prefer C++ compatibility, all things being equal.


I think Sam has a reasonable point. Of course, it need not
always be the case, but clearly many C programmers
do -- and should -- worry about what C++ compilers will think.


Since C translation units can be linked into C++ programs, why can't
they just compile their .c files with a C compiler, even when they're
part of a C++ project?


They can. But to require everybody do so is not always
sufficient, just like not requiring them to do so isn't.
When/If an obvious gain can be made, it should be considered,
in context.
--
Greg Comeau/4.3.3:Full C++03 core language + more Windows backends
Comeau C/C++ ONLINE ==> http://www.comeaucomputing.com/tryitout
World Class Compilers: Breathtaking C++, Amazing C99, Fabulous C90.
Comeau C/C++ with Dinkumware's Libraries... Have you tried it?
Nov 13 '05 #14
Arthur J. O'Dwyer <aj*@andrew.cmu.edu> wrote:
I think the simplest solution has been determined to be:

if (some_condition)
return (errno = EINVAL, (void *) NULL);

Still, I agree that this is almost certainly obfuscation. Have
you considered my /idiom du jour/,

if (some_condition1)
goto exit_failure1;
if (some_condition2)
goto exit_failure2;
...

exit_failure1:
errno = EINVAL;
return NULL;

exit_failure2:
errno = ENAMETOOLONG;
return NULL;

Very compact, and has the added bonus that all the "exit" code is in
one place. That means it's harder to miss a free(), and easier to
figure out all the possible return codes (which should be documented
anyway, of course, but still..).


yes ;) i use that extensively, tho i usually limit it to a simple "goto
fail", otherwise things seem a little too cluttered to me (trying to juggle
multiple labels). instead i'll initialize the relevent values so that the
fail section knows what to clean up and what not to. and so i might do
something like:

if (cond) {
errno = EINVAL;
goto fail;
}

anyhoo, this has been an interesting thread, at least for myself.

thanx all.

[END OF THREAD]

Nov 13 '05 #15

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Alex Vinokur | last post by:
------ foo.cpp ------ #include <iostream> using namespace std; int main() { #define FACTOR 10 for (unsigned long array_size = 1; ; array_size *= FACTOR) { int* p = new int;
3
by: Dimitri Furman | last post by:
SQL Server 2000 SP3. Is it possible for the @@ROWCOUNT function to return NULL after a statement? I am troubleshooting a relatively large stored procedure with multiple SELECT statements and a...
8
by: Daniel Billingsley | last post by:
Suppose I have a method that returns some type of object, and in that method I have a try...catch block and just throw my own exception when I catch one. The compiler insists that all code paths...
3
by: Dean L. Howen | last post by:
I tries to search for SQL server using SQLDMO, but it alway return null although I have updated SQL to sp3 Please tell me more.
3
by: Digital Fart | last post by:
I have the following function that returns a struct public struct layout { public string str; public int i; } function in some class where i loop through an arraylist of structs
3
by: Daves | last post by:
a get { ... } for public property SelectedValue returns DateTime type to be used as a parameter in a Sql update query but I'd like it to return "empty" if no date has been selected... I cannot use...
2
by: Tim Lambert | last post by:
Has anyone seen this happen? I have seen it on a system that is making lots and lots of short lived connections. At this point I'm not sure of the high water mark for the number of connections. ...
2
by: mlevit | last post by:
Hi, I've written my own JavaScript and used a couple of codes to set and get cookies from the net I found. When I set the cookie I can see it in my browser, it is set with the right value and...
9
by: Francois Grieu | last post by:
When running the following code under MinGW, I get realloc(p,0) returned NULL Is that a non-conformance? TIA, Francois Grieu #include <stdio.h> #include <stdlib.h>
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.