cast

B

Bill Cunningham

I have written this wrapper function that seems to compile into an
object file just fine.

#include "main.h"

struct addrinfo ad, *adp;
static int stat;
struct addrinfo **ginfo(char *port)
{
memset(&ad, '\0', sizeof ad);
ad.ai_family = AF_INET;
ad.ai_socktype = SOCK_STREAM;
ad.ai_flags = AI_PASSIVE;
if ((stat = getaddrinfo(NULL, port, &ad, &adp)) != 0) {
fprintf(stderr, "Error: %s\n", gai_strerror(stat));
exit(EXIT_FAILURE);
}
return (struct addrinfo **)stat;
}

Just above is the code in question. I had to make this cast to return my
function's return type because stat is an int. I was told that when code is
written right; casts shouldn't be neccesary. Should I make any changes to
this? Is what I just stated about casts correct?

Bill
 
K

Keith Thompson

Bill Cunningham said:
I have written this wrapper function that seems to compile into an
object file just fine.

#include "main.h"

struct addrinfo ad, *adp;
static int stat;
struct addrinfo **ginfo(char *port)
{
memset(&ad, '\0', sizeof ad);
ad.ai_family = AF_INET;
ad.ai_socktype = SOCK_STREAM;
ad.ai_flags = AI_PASSIVE;
if ((stat = getaddrinfo(NULL, port, &ad, &adp)) != 0) {
fprintf(stderr, "Error: %s\n", gai_strerror(stat));
exit(EXIT_FAILURE);
}
return (struct addrinfo **)stat;
}

Just above is the code in question. I had to make this cast to return my
function's return type because stat is an int. I was told that when code is
written right; casts shouldn't be neccesary. Should I make any changes to
this? Is what I just stated about casts correct?

Read the documentation for the getaddrinfo() function. Pay particular
attention to the return value, which is of type int. Ask yourself
whether it makes sense to treat that return value as a pointer.

You're right to be suspicious of the cast.
 
L

Lew Pitcher

I have written this wrapper function that seems to compile into an
object file just fine.

#include "main.h"

struct addrinfo ad, *adp;
static int stat;
struct addrinfo **ginfo(char *port)
{
memset(&ad, '\0', sizeof ad);
ad.ai_family = AF_INET;
ad.ai_socktype = SOCK_STREAM;
ad.ai_flags = AI_PASSIVE;
if ((stat = getaddrinfo(NULL, port, &ad, &adp)) != 0) {
fprintf(stderr, "Error: %s\n", gai_strerror(stat));
exit(EXIT_FAILURE);
}
return (struct addrinfo **)stat;
}

Just above is the code in question. I had to make this cast to return
my
function's return type because stat is an int. I was told that when code
is written right; casts shouldn't be neccesary. Should I make any changes
to this? Is what I just stated about casts correct?

Bill,

I've looked over your function, and (disregarding a couple of minor WTFs
within the code) I have a question for you: Why did you design this
function to return a pointer to a pointer to a struct addrinfo? Your code
will /never/ return such a pointer, instead (when it returns at all) it
returns an int /cast/ as such a pointer. Why not just design the function
to return an int, and discard that cast completely? Such as...

struct addrinfo ad, *adp;
static int stat;
int ginfo(char *port)
{
memset(&ad, '\0', sizeof ad);
ad.ai_family = AF_INET;
ad.ai_socktype = SOCK_STREAM;
ad.ai_flags = AI_PASSIVE;
if ((stat = getaddrinfo(NULL, port, &ad, &adp)) != 0) {
fprintf(stderr, "Error: %s\n", gai_strerror(stat));
exit(EXIT_FAILURE);
}
return stat;
}

But, even this is a bit dodgy, as the function will /always/ return
(int) 0 (or never return at all).

I suspect that you don't really want to return stat, but instead want to
return ad or *adp, when the getaddrinfo() call returns 0, and /something
else/ when the getaddrinfo() call returns non-zero. Right now, you /only/
return when getaddrinfo() returns zero, and *exit()* (abort the entire
program) when getaddrinfo() returns non-zero.

Some advice: when designing a function, first decide /what sort of
information/ you need the function to return. /Then/ write the function to
return that sort of information. In your original code, you had decided
that you needed your ginfo() function to return a pointer to a pointer to a
struct addrinfo. So, why did you instead return an int (guaranteed to be
0) /cast/ as such a pointer?
 
B

Bill Cunningham

Lew Pitcher wrote:

[snip]
I've looked over your function, and (disregarding a couple of minor
WTFs within the code) I have a question for you: Why did you design
this function to return a pointer to a pointer to a struct addrinfo?

Originally I returned a &adp but since getadrrinfo () returns an int I
did change it to return stat. Then I redesigned it as the code I posted.

What does WTF mean?
Your code will /never/ return such a pointer, instead (when it
returns at all) it returns an int /cast/ as such a pointer. Why not
just design the function to return an int, and discard that cast
completely? Such as...

struct addrinfo ad, *adp;
static int stat;
int ginfo(char *port)
{
memset(&ad, '\0', sizeof ad);
ad.ai_family = AF_INET;
ad.ai_socktype = SOCK_STREAM;
ad.ai_flags = AI_PASSIVE;
if ((stat = getaddrinfo(NULL, port, &ad, &adp)) != 0) {
fprintf(stderr, "Error: %s\n", gai_strerror(stat));
exit(EXIT_FAILURE);
}
return stat;
}

I tried that and it compiled well. I also tried return &adp; and it
worked fine.
But, even this is a bit dodgy, as the function will /always/ return
(int) 0 (or never return at all).

I suspect that you don't really want to return stat, but instead want
to return ad or *adp,

I'm not really sure on that one.

when the getaddrinfo() call returns 0, and
/something else/ when the getaddrinfo() call returns non-zero. Right
now, you /only/ return when getaddrinfo() returns zero, and *exit()*
(abort the entire program) when getaddrinfo() returns non-zero.
[...]

Bill
 
L

Lew Pitcher

Lew Pitcher wrote:

[snip]
I've looked over your function, and (disregarding a couple of minor
WTFs within the code) I have a question for you: Why did you design
this function to return a pointer to a pointer to a struct addrinfo?

Originally I returned a &adp but since getadrrinfo () returns an int I
did change it to return stat. Then I redesigned it as the code I posted.

OK, but /why/ did you change to return stat? What benefit did you see in
returning stat (which, by your program logic will /always/ be zero) rather
than &adp? What did you expect the calling function to do with the stat
value?
What does WTF mean?

"What The F**k"
I tried that and it compiled well. I also tried return &adp; and it
worked fine.

Not with that function definition, it doesn't.
int ginfo(char *port)
returns an int, and coercing a struct addrinfo ** into an int isn't the way
to go. OTOH, if you changed ginfo to
struct addrinfo **ginfo(char *port)
then you could properly return &adp.

But then again, why bother? After all, adp is defined at file scope; there's
no need for ginfo() to return it. The caller could simply
ginfo(some_port_number);
if (adp != NULL) {/* do something with adp*/}
and likewise for ad, as it is a "global" as well.
I'm not really sure on that one.

If you're not sure, then /why/ did you write the function? You write
functions to perform specific actions, and to return /specific
information/. If you don't know what you want to return then you shouldn't
write the function.
when the getaddrinfo() call returns 0, and
/something else/ when the getaddrinfo() call returns non-zero. Right
now, you /only/ return when getaddrinfo() returns zero, and *exit()*
(abort the entire program) when getaddrinfo() returns non-zero.
[...]

Bill
 
B

Bill Cunningham

Hum I saw that getaddrinfo () returned an int so I thought that was
what I wanted my wrapper function to return. But I was a little suspicous
because of getaddrinfo()'s 4th parameter taking a pointer. Taking and
returning is two different things if I understand correctly. Should you
return what a another function takes as a parameter?

Bill
 
L

Lew Pitcher

Hum I saw that getaddrinfo () returned an int so I thought that was
what I wanted my wrapper function to return.

OK.
Now, think of /why/ you wanted your wrapper to return the int returned by
getaddrinfo(). Of what use is that value to the function that /calls/ your
function? If it is of no use, then why return it (or any other value)?
But I was a little suspicous because of getaddrinfo()'s 4th parameter
taking a pointer.

Which has nothing to do with what /you/ wanted /your/ function to return.
Taking and returning is two different things if I understand correctly.

Yes. In general, you write functions
- to (optionally) accept information from the caller, so as to influence
the behaviour of the function,
- to (optionally) perform some activity, and
- to (optionally) provide some information to the caller, so as to inform
the caller of the results of the function
Should you return what a another function takes as a parameter?

No. A function should return a value that is meaningful to the caller. This
value /might/ be a parameter to another function, or it might not.

Look, you really need to understand the techniques of programming. Do
yourself a favour and look up "Top down structured programming". Read some
books (there are plenty of them out there) on the subject. /Comprehend/
what it is you want to do.

Right now, you are trying to build a house by looking at the pretty pictures
in "Better Homes and Gardens". You built the kitchen walls, and are now
asking us why your kitchen doesn't lead to the dining room. And, why the
floor sags (not having built your foundations yet). If you continue this
way, all you'll have is a pile of lumber, in splinters, and no house. Learn
how to /program/ first, and in conjunction with learning how to program in
C.
 
B

Bill Cunningham

Lew said:
Yes. In general, you write functions
- to (optionally) accept information from the caller, so as to
influence the behaviour of the function,
- to (optionally) perform some activity, and
- to (optionally) provide some information to the caller, so as to
inform the caller of the results of the function.

So which of the above would be returning &adp?

Bill
 
L

Lew Pitcher

So which of the above would be returning &adp?

Let's go over that again, Bill

In general, you write functions
- to (optionally) accept information from the caller, so as to
influence the behaviour of the function,
**These are the function arguments**

- to (optionally) perform some activity, and
** This is the function body **

- to (optionally) provide some information to the caller, so as to
inform the caller of the results of the function.
** This is the function's return value **
 
K

Keith Thompson

Lew Pitcher said:
Let's go over that again, Bill

In general, you write functions
- to (optionally) accept information from the caller, so as to
influence the behaviour of the function,
**These are the function arguments**

- to (optionally) perform some activity, and
** This is the function body **

- to (optionally) provide some information to the caller, so as to
inform the caller of the results of the function.
** This is the function's return value **

Though sometimes the semantic line between the return value and the
parameters can be a bit vague.

For example, say you want to write a function that computes a square
root (yes, sqrt() already exists in the standard library, but we'll
ignore that). There are really two piece of information you want to
pass back to the caller: the square root of the argument, and an
indication of whether an error occurred.

Since C doesn't have either exceptions or multi-valued functions
(well, you could return a struct, but that's clumsy), you typically
have to divide the information between the return value and pointer
parameters.

You might write this:

/*
* Return an error indication, store result via pointer arg */
*/
int square_root(double x, double *result_ptr) {
if (x < 0.0 or result_ptr == NULL) {
return -1; /* an error indicator */
}
else {
*result_ptr = /* compute the result here */;
return 0;
}
}

or this:

/*
* Return the result, store error indication via pointer arg
*/
#define NO_ERROR 0
#define NEGATIVE_ARGUMENT 1

double square_root(double x, int *error) {
if (x < 0.0) {
if (error != NULL) {
*error = NEGATIVE_ARGUMENT;
}
return 0.0;
}
else {
*error = NO_ERROR;
return /* compute the result here */;
}
}

or this:

/*
* Return the result, store error indication in errno
*/
double square_root(double x) {
if (x < 0.0) {
errno = EDOM;
return 0.0;
}
else {
return /* compute the result here */;
}
}
 
B

Bill Cunningham

Keith said:
Though sometimes the semantic line between the return value and the
parameters can be a bit vague.

For example, say you want to write a function that computes a square
root (yes, sqrt() already exists in the standard library, but we'll
ignore that). There are really two piece of information you want to
pass back to the caller: the square root of the argument, and an
indication of whether an error occurred.

Since C doesn't have either exceptions or multi-valued functions
(well, you could return a struct, but that's clumsy), you typically
have to divide the information between the return value and pointer
parameters.

You might write this:
[snip for Brevity]

Loud and clear Kieth. Thanks much. I was a little confused by the way
Lew put it.

Bill
 
P

Phil Carmody

Lew Pitcher said:
On April 16, 2010 12:18, in comp.lang.c, (e-mail address removed) wrote:
Bill,

I've looked over your function, and (disregarding a couple of minor WTFs

Minor what-the-****'s?

What the **** is a minor what-the-****?

If it was minor it, quite simply, wasn't a 'what-the-****'.

Phil
 
K

Kenny McCormack

So which of the above would be returning &adp?

Bill

Heh! Still at it eh Bill? Nice. Unbelievable that they still fall for
it.[/QUOTE]

What's funny is how they (the regs) deal with the various "trolls" here
- each in kind, appropriate to their ability to be flamed.

For example:

1) Jacob and Nilges get full play, because they both wear their hearts
fully on their sleeves. Both are entirely earnest in their postings
and get full play from the regs (despite all protestations to the
contrary from the regs that they should stop "feeding the trolls".
Fact is, they never will, because it is too much fun for them -
feeds all their little psycho-sexual needs)

2) You (rgrdev) get minimal play. Your stuff is almost beyond reproach,
but you do, from time-to-time, post stuff that they can get their
hooks into. And, of course, when this happens, they can't pass up
the opportunity (again, despite protestations to the contrary about
how they should stop "feeding the trolls")

3) Me. I get no play, because my stuff is utterly perfect in all
particulars, and thus utterly impervious to reg attack. So, in this
case, at least, they are true to their pledge to stop "feeding the
trolls".

--
(This discussion group is about C, ...)

Wrong. It is only OCCASIONALLY a discussion group
about C; mostly, like most "discussion" groups, it is
off-topic Rorsharch revelations of the childhood
traumas of the participants...
 
J

jacob navia

Richard a écrit :
Heh! Still at it eh Bill? Nice. Unbelievable that they still fall for
it.

I wrote around 6 messages to "Bill" with this contents:

The truth is that you were "studying sockets" six years ago in
comp.os.ms-windows.programmer.win32 and
microsoft.public.win32.programmer.ole, where you were asking Win32
programmers WinSock-flavoured versions of the questions that you are now
asking Unix programmers. Your postings would have the world think that
you have made zero progress in learning how to compile even basic C
programs in eight years, when you first started talking about how you
were using DJGPP and mingw. Indeed you are trying to convince people
that you have less grasp of things now than you did when you were
talking about recompiling gcc in comp.os.linux.development.apps in 2005,
or about the Standard C library in kernel-mode code in comp.lang.c back
in 2003, or about microkernels in comp.os.linux.development.system in
2002, or about how to use DJGPP in comp.os.linux in 2002, or about Win32
API programming in comp.programming in 2002.

More and more people are not going to fall for this any more. Jens
Thoms Toerring has sussed you. santosh and Mark McIntyre sussed you in
2005. They'll all no doubt be disappointed to learn that it took them
longer than Eric Tomson, who sussed you in 2002 when you asked Linus
Torvalds silly questions on the IETF mailing list.



The only answer was from thompson that asked me to stop posting those
messages. "Bill" never replied.

Of course.

The "regs" go on with their work of systematically destroying this group
by ensuring that only people that despise C (nilges) or trolls like
"Bill" get endless replies, lowering the quality of this group and
making any of the few people here that are interested in C stop reading.
 
B

Ben Bacarisse

pete said:
I've never been able to understand why somebody
would write code to check if a domain error had occured, instead
of writing code to catch the domain error before it occured.

if (square_root(x, result_ptr) != -1) {
func(*result_ptr);
} else {
}

vs.

if (x >= 0) {
func(sq_rt(x));
} else {
}

Sometimes the range error is hard to predict due to implementation
differences (e.g. exp(x)) and sometimes it is (almost) as hard to
predict as the result of the computation (e.g. matrix inversion). In
both these cases, testing for a range error makes sense.
 
K

Kenny McCormack

I like to give them an angle. What scares me is how utterly predictable
the responses are. All part of being "regs" I guess.

Yes. Well said, and well put.

Incidentally, I mistakenly left Bill out of my list. He should also be
on the "get full play" list, even though he's quite different than Jacob
and Nilges.

You put it well as:

He's a good one though. He appeals to those dozy enough to think
their almost worthless opinions are suddenly enough to help a less
fortunate.

Or, as we used to say, WebTV exists to give AOLers someone to look down
upon (and be "helpful" to).

--
(This discussion group is about C, ...)

Wrong. It is only OCCASIONALLY a discussion group
about C; mostly, like most "discussion" groups, it is
off-topic Rorsharch revelations of the childhood
traumas of the participants...
 
N

Nick Keighley

On April 16, 2010 14:06, in comp.lang.c, (e-mail address removed) wrote:

Look, you really need to understand the techniques of programming. Do
yourself a favour and look up "Top down structured programming".

blast from the past. Do people still do that?

Read some
books (there are plenty of them out there) on the subject. /Comprehend/
what it is you want to do.

Right now, you are trying to build a house by looking at the pretty pictures
in "Better Homes and Gardens". You built the kitchen walls, and are now
asking us why your kitchen doesn't lead to the dining room. And, why the
floor sags (not having built your foundations yet). If you continue this
way, all you'll have is a pile of lumber, in splinters, and no house. Learn
how to /program/ first, and in conjunction with learning how to program in
C.

do people really learn to program likle that? First learn a buch of
theory then learn a programming language? They taught me a programming
language as they taught me to program. Though I'd seen flow diagrams
and basic programs before I actually laid hands on a programming
language (computers weren't ubiquitous then). I'd have though most
people would need something more concrete than a theoretical outline.
You're right (if he's genuine) he's tackling problems that are far too
hard. He should be drawing christmas trees and understanding how
programs like that work. A kinder language for beginners might be what
he needs. Python?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,062
Latest member
OrderKetozenseACV

Latest Threads

Top