wit's end

F

Frank Silvermann

#include <stdio.h>
#include <stdlib.h>
int * get_an_int(void);
int main(void)
{
int * qt;
qt = get_an_int(void);
printf ("t is\n", *qt);
printf ("tja\n");
return 0;
}

int * get_an_int(void)
{
int t;
int * pt;
pt = malloc (sizeof*pt);
t = 41;
pt = & t;
return pt;
}
/* end source */
I think I'm going cross-eyed. I can't get this to compile. The
compiler's first objection is to the line:
qt = get_an_int(void);
Ideas? frank
 
R

Roberto Waltman

#include <stdio.h>
#include <stdlib.h>
int * get_an_int(void);
int main(void)
{
int * qt;
qt = get_an_int(void);
printf ("t is\n", *qt);
printf ("tja\n");
return 0;
}

int * get_an_int(void)
{
int t;
int * pt;
pt = malloc (sizeof*pt);
t = 41;
pt = & t;
return pt;
}
/* end source */
I think I'm going cross-eyed. I can't get this to compile. The
compiler's first objection is to the line:
qt = get_an_int(void);
Ideas? frank

Should be :
qt = get_an_int();
 
R

Richard Heathfield

Frank Silvermann said:
#include <stdio.h>
#include <stdlib.h>
int * get_an_int(void);
int main(void)
{
int * qt;
qt = get_an_int(void);
printf ("t is\n", *qt);
printf ("tja\n");
return 0;
}

int * get_an_int(void)
{
int t;
int * pt;
pt = malloc (sizeof*pt);

Hello, memory. (If it worked.)
t = 41;
pt = & t;

Bye-bye, memory, hello pointer to local object that's about to die.
return pt;
}
/* end source */
I think I'm going cross-eyed. I can't get this to compile. The
compiler's first objection is to the line:
qt = get_an_int(void);

Drop the void.

And change: pt = &t; to pt[0] = t;
 
N

Nelu

Frank Silvermann said:
#include <stdio.h>
#include <stdlib.h>
int * get_an_int(void);
int main(void)
{
int * qt;
qt = get_an_int(void);
You are sending a parameter called void to get_an_int. The function
takes no parameters (but you supply one) and, also, it may complain
about sending one that's the name of a type, although that's masked by
the fact that you are not supposed to send a parameter.
printf ("t is\n", *qt);
It will give you a warning here saying that you give it too many
parameters. It's not an error, just a warning, and it will not print
your value. Add a %d before \n if you want to print the value of *qt.
printf ("tja\n");
return 0;
}

int * get_an_int(void)
{
int t;
int * pt;
pt = malloc (sizeof*pt);
pt may be NULL. You must check it!
t = 41;
pt = & t;
You malloc-ed pt and now you tell it to point somewhere else.
The allocated memory is not freed. If you want to copy the value do *pt=t;
return pt;
pt probably points to an area that's no longer yours.
 
J

Joe Smith

Roberto Waltman said:
Should be :
qt = get_an_int();
God! I understand the need for syntax, but sometimes the commitment is
masochistic. Is it just me with a silly implementation or unusual
perspectives on computer languages, or is there a better reason that my
compiler didn't want to see the argument void as the lack of an argument?
frank
 
K

Keith Thompson

Frank Silvermann said:
#include <stdio.h>
#include <stdlib.h>
int * get_an_int(void);
int main(void)
{
int * qt;
qt = get_an_int(void);
printf ("t is\n", *qt);
printf ("tja\n");
return 0;
}

int * get_an_int(void)
{
int t;
int * pt;
pt = malloc (sizeof*pt);
t = 41;
pt = & t;
return pt;
}
/* end source */
I think I'm going cross-eyed. I can't get this to compile. The
compiler's first objection is to the line:
qt = get_an_int(void);
Ideas? frank

Please indent your code. It's difficult to read when it's all shoved
against the left margin like that.

In a function call, you need
The name of the function
A left parenthesis
Zero or more expressions (the arguments) separated by commas
A right parenthesis
The keyword "void" is none of these. It's used to indicate no
parameters in a function declaration; it's not used in a function
call.

The syntax for calling a function with no arguments is "func()".

In your printf call:
printf ("t is\n", *qt);
you don't provide a conversion specifier for the arguments. Since *qt
is of type int, you want:

printf ("t is %d\n", *qt);

Your get_an_int() function returns a pointer to int, and it does a lot
of extra work to do so. Why not just return an int?

The value it returns is the address of a local variable. That
variable ceases to exist when you leave the function; when the pointer
value gets back to the caller, it's no longer valid (it points to
memory that you no longer own). If you really want to return a
pointer to int, you need to allocate an int, not a pointer.

You assign pt the result of malloc(), then you assign pt the address
of t. You've just lost your only pointer to the allocated memory;
this is a memory leak. (You never try to free() it anyway).
 
K

Keith Thompson

Richard Heathfield said:
And change: pt = &t; to pt[0] = t;

Or *pt = t (equivalent and, IMHO, clearer, since pt points to a single
int, not an array).

But I don't think making just those changes will result is a correct
program.
 
K

Keith Thompson

Keith Thompson said:
int * get_an_int(void)
{
int t;
int * pt;
pt = malloc (sizeof*pt);
t = 41;
pt = & t;
return pt;
}
[...]
The value it returns is the address of a local variable. That
variable ceases to exist when you leave the function; when the pointer
value gets back to the caller, it's no longer valid (it points to
memory that you no longer own). If you really want to return a
pointer to int, you need to allocate an int, not a pointer.

Please ignore that last sentence; I mis-read the code.
 
F

Frank Silvermann

Keith said:
Richard Heathfield said:
And change: pt = &t; to pt[0] = t;

Or *pt = t (equivalent and, IMHO, clearer, since pt points to a single
int, not an array).

But I don't think making just those changes will result is a correct
program.
If you had bet your thought, you'd be in the chips right:


#include <stdio.h>
#include <stdlib.h>
int * get_an_int(void);
int * pass_pointer_triv(int *);
int main(void)
{
int *rt, *qt;
qt = get_an_int();
rt = pass_pointer_triv(qt);
printf ("t is %d\n", *rt);
printf ("tja\n");
return 0;
}

int * get_an_int(void)
{
int t;
int * pt;
pt = malloc (sizeof*pt);
t = 41;
pt[0] = t;
return pt;
}

pass_pointer_triv(int *a)
{
int t;
t = &a;
printf("t is %d\n", t);
return a;
}
/* end source begin what my compiler thinks*/

C:\MSDEV\Projects\tja25\Text4.c(29) : error C2040: 'pass_pointer_triv' :
'int (int *)'
/* end output of cl.exe */
void is an analog of NULL. My night comes quickly to nought. frank
 
R

Richard Heathfield

Keith Thompson said:
Richard Heathfield said:
And change: pt = &t; to pt[0] = t;

Or *pt = t (equivalent and, IMHO, clearer, since pt points to a single
int, not an array).

Oh, does it? I didn't read it that closely, I'm afraid.
But I don't think making just those changes will result is a correct
program.

Possibly not. I didn't have time to do a full analysis. I saw one other
reply, and thought "he's missed the assignment problem", so I pointed that
out. It wouldn't surprise me if there were other problems too.
 
F

Frank Silvermann

Richard said:
Frank Silvermann said:

Make that: t = *a;
Since it gave me the same error, I'm going to assume that I'm the
subject of a practical joke or a guy who needs to stop looking at a
screen and dine. As an Englishman, you might not know how the rest of
look forward to putting something in our mouths that tastes better than
sand, and that our failure to continue working has a POSITIVE Pavlonian
response, but you can certainly see that I've reached the point of
diminishing returns as it regards syntax. cheers, frank
 
K

Keith Thompson

Joe Smith said:
Roberto Waltman said:
qt = get_an_int(void);
[...]
Should be :
qt = get_an_int();
God! I understand the need for syntax, but sometimes the commitment is
masochistic. Is it just me with a silly implementation or unusual
perspectives on computer languages, or is there a better reason that my
compiler didn't want to see the argument void as the lack of an argument?
frank

Was the above paragraph written by Joe Smith, or by Frank Silvermann?
The article appears to have been posted by Joe Smith, but it's signed
"frank". Judging by the headers, it seems likely that they're the
same person. I have no objection to pseudonyms, but using a
consistent name makes it easier to follow the discussion.

Anyway ...

Do you really want compilers to try to guess what you mean? Either
the compiler follows the rules of the language, or it doesn't. The
syntax for a function call with no arguments is func(); typing
func(void) instead is an understandable error, but not one I've ever
seen before.

It might be nice if the compiler gave you a hint along with the error
message, something like:

syntax error (do you mean func() rather than func(void)?)

But if it silently assumed that you really meant func(), it wouldn't
be doing you any favors. Your code would still fail to compile on any
other compiler that didn't happen to make that particular guess.

func(void) could have been made valid syntax in the language, a
synonym for func(), but I see no benefit in doing so. As a
programmer, you just have to get it right.
 
M

Michael Mair

Frank said:
Since it gave me the same error, I'm going to assume that I'm the
subject of a practical joke

You are not.
or a guy who needs to stop looking at a
screen and dine. As an Englishman, you might not know how the rest of
look forward to putting something in our mouths that tastes better than
sand, and that our failure to continue working has a POSITIVE Pavlonian
response, but you can certainly see that I've reached the point of
diminishing returns as it regards syntax.

Could you please can this drivel and your childish demeanour?

Try to concentrate on C when writing to comp.lang.c and please,
please do not try to be funny.
Stay with one alias -- I don't care whether it's the original m.,
"frank silvermann", "joe smith", or "furunculus, inventor of the
any key".

Half of your mistakes exhibited here throughout the last month
could have been avoided if you'd just really read the answers
you get and think thoroughly about them.

-Michael
 
C

Chris Torek

In a function call, you need
The name of the function
A left parenthesis
Zero or more expressions (the arguments) separated by commas
A right parenthesis
The keyword "void" is none of these. It's used to indicate no
parameters in a function declaration; it's not used in a function
call.

The syntax for calling a function with no arguments is "func()".

As an aside, the reason for this bizarre asymmetry is historic.

In Ancient (or "K&R 1st Edition") C, there were no prototypes.
There were only declarations. If f() always required exactly three
arguments, and then returned a value of type "int *", one had to
write:

int *f();

int main(void) {
int *p1, *p2;
p1 = f(1, "23", 456.789);
...
}

This meant that C compilers in general could not check the actual
arguments. Here f() needs exactly three; obviously the first is
an "int", the second a "char *", and the third a "double". But in
K&R-1 C, if you accidentally called it improperly:

p2 = f("oops");

the compiler silently accepted it, and your code bombed out at
runtime (if you were lucky; if you were unlucky it ran anyway,
and did ... something, but who knows what).

In 1989, the original ANSI C standard adopted the newfangled
"prototype" declarations from C++ (or what was C++ at that time,
which was a language that is almost but not entirely unlike today's
C++ :) ). To declare that f() took exactly three arguments, of
type "int", "char *", and "double", and returned "int *", one now
wrote:

int *f(int, char *, double);

However, ANSI C had to permit the old-style non-prototype declaration,
using it to mean: "We know what kind of value f() returns, but we
have no idea how many arguments it takes, so just accept whatever
the programmer puts in there and hope he gets it right."

That left a problem: if "int *f();" meant "f() takes some unknown
number of arguments, so hope the programmer gets it right", how
could a programmer say "f() takes NO arguments, and I want you,
Mr Compiler, to complain if I accidentally get this wrong"?

The answer was to add this "(void)" syntax. As a very special
case, if you wanted to write a prototype declaration for f()
and say "this function takes no arguments, NONE AT ALL EVER
thank you very much", you had to write:

int *f(void);

The "void" filled in the empty space, without putting anything
"real" in there. Now the C compiler could tell the difference
between "programmer did not say" and "programmer did say, and
he said `there must be nothing'".

C++ never required the "void", because C++ always had prototypes,
so "int *f()" always meant "f() takes no arguments".

When the X3J11 (ANSI C) committee invented this new "f(void)"
thing, they could have, but did not, change the syntax of actual
calls to permit a (useless) "void" keyword in calls as well.
So:

int *f(void);

is a prototype saying "f() takes no arguments", and:

int *ip = f();

contains a correct call to f(), supplying those "no arguments".
 
A

av

#include <stdio.h>
#include <stdlib.h>
int * get_an_int(void);
int main(void)
{
int * qt;
qt = get_an_int(void);
printf ("t is\n", *qt);
printf ("tja\n");
return 0;
}

int * get_an_int(void)
{
int t;
int * pt;
pt = malloc (sizeof*pt);
t = 41;
pt = & t;
return pt;
}
/* end source */
I think I'm going cross-eyed. I can't get this to compile. The
compiler's first objection is to the line:
qt = get_an_int(void);

it has to be qt = get_an_int();
Ideas? frank

what is returned from malloc has to be check and free with free()

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

int * get_an_int(void);

int main(void)
{int *qt;
qt = get_an_int();
if(qt==0) return 0;

printf ("t is %d\n", *qt);
printf ("tja\n");

free(qt);
return 0;
}

int* get_an_int(void)
{int *pt;
pt = malloc (sizeof *pt);
if( pt==0 ) return 0;
*pt = 41 ;
return pt;
}

above seems good
C:> prog
t is 41
tja
 
A

ada

Frank Silvermann said:
#include <stdio.h>
#include <stdlib.h>
int * get_an_int(void);
int main(void)
{
int * qt;
qt = get_an_int(void);
printf ("t is\n", *qt);
printf ("tja\n");
return 0;
}

int * get_an_int(void)
{
int t;
int * pt;
pt = malloc (sizeof*pt);
t = 41;
pt = & t;
return pt;
}
/* end source */
I think I'm going cross-eyed. I can't get this to compile. The
compiler's first objection is to the line:
qt = get_an_int(void);
Ideas? frank
first, your ref a temp variable ,so you will get runtime error.
second,your malloc some memory,BUT you don't free it.
 
J

Joe Smith

Chris Torek said:
As an aside, the reason for this bizarre asymmetry is historic.

In Ancient (or "K&R 1st Edition") C, there were no prototypes.
There were only declarations. If f() always required exactly three
arguments, and then returned a value of type "int *", one had to
write:

int *f();

int main(void) {
int *p1, *p2;
p1 = f(1, "23", 456.789);
...
}

This meant that C compilers in general could not check the actual
arguments. Here f() needs exactly three; obviously the first is
an "int", the second a "char *", and the third a "double". But in
K&R-1 C, if you accidentally called it improperly:

p2 = f("oops");

the compiler silently accepted it, and your code bombed out at
runtime (if you were lucky; if you were unlucky it ran anyway,
and did ... something, but who knows what).

In 1989, the original ANSI C standard adopted the newfangled
"prototype" declarations from C++ (or what was C++ at that time,
which was a language that is almost but not entirely unlike today's
C++ :) ). To declare that f() took exactly three arguments, of
type "int", "char *", and "double", and returned "int *", one now
wrote:

int *f(int, char *, double);

However, ANSI C had to permit the old-style non-prototype declaration,
using it to mean: "We know what kind of value f() returns, but we
have no idea how many arguments it takes, so just accept whatever
the programmer puts in there and hope he gets it right."

That left a problem: if "int *f();" meant "f() takes some unknown
number of arguments, so hope the programmer gets it right", how
could a programmer say "f() takes NO arguments, and I want you,
Mr Compiler, to complain if I accidentally get this wrong"?

The answer was to add this "(void)" syntax. As a very special
case, if you wanted to write a prototype declaration for f()
and say "this function takes no arguments, NONE AT ALL EVER
thank you very much", you had to write:

int *f(void);

The "void" filled in the empty space, without putting anything
"real" in there. Now the C compiler could tell the difference
between "programmer did not say" and "programmer did say, and
he said `there must be nothing'".

C++ never required the "void", because C++ always had prototypes,
so "int *f()" always meant "f() takes no arguments".

When the X3J11 (ANSI C) committee invented this new "f(void)"
thing, they could have, but did not, change the syntax of actual
calls to permit a (useless) "void" keyword in calls as well.
So:

int *f(void);

is a prototype saying "f() takes no arguments", and:

int *ip = f();

contains a correct call to f(), supplying those "no arguments".

My other newsreader forgot its password, so I apologize in advance for the
lack of continuity. My newsreaders/server frustrate no one more so than me.
What an interesting account. Would you describe 'void' as an analog to
'NULL'? furunculus
 
J

Joe Wright

Joe said:
My other newsreader forgot its password, so I apologize in advance for the
lack of continuity. My newsreaders/server frustrate no one more so than me.
What an interesting account. Would you describe 'void' as an analog to
'NULL'? furunculus
No. NULL is a macro in stdio.h which expands to the null pointer
constant, usually 0 or (void*)0 depending on implementor's taste.

The term 'void' was introduced in C89 to fill out prototype declarations
so that 'int foo();' which could take any number of arguments, might
become 'int foo(void);' so as to take no arguments.

C89 also introduced (void*) as a type and declares that void* values may
be assigned to any object type.
 
Y

Your Uncle

"Michael Mair"
You are not.


Could you please can this drivel and your childish demeanour?

Try to concentrate on C when writing to comp.lang.c and please,
please do not try to be funny.
Stay with one alias -- I don't care whether it's the original m.,
"frank silvermann", "joe smith", or "furunculus, inventor of the
any key".

Half of your mistakes exhibited here throughout the last month
could have been avoided if you'd just really read the answers
you get and think thoroughly about them.
One thing about clc is that we write. This writing goes through a
newsreader to at least one server to another newsreader. Already the
potential for miscommunication is high. And writing is personal, even
source C. Especially source C. There are replies, and these amount to
editing. Writers need editors but resent them, until an irrational
attachment to what got edited dissipates. I had a hard night last night
remembering, in those myriad reconstructions, Michael's last words. He
chuckled and repeated my punchline, "Das sind keine Erdbeeren." It is, of
course, not your problem that you are the same nationality and Vorname of my
dead friend, nor are the events of Berlin in 1980's topical in clc. We dish
it and take it around here. It's true that I made fun of English cuisine
with the specific intention that it fall under an Englishman's eyes. Maybe I
offended. The only explanation I can find for the cuisine is the expectation
that the Luftwaffe were going to come before it was injested. I'm going to
hop back into my development suite and try to avoid the fiascos of
yesterday, while moving my projects along. If my compiler wants to abuse me
like she did yesterday, I promise no invectives to clc, but pull_the_plug()
and go play poker. gruss, furunculus
 

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

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top