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

Inconsistent

P: n/a
Could someone comment on this code please.

1. Are the comments in it correct?

2. Why does sizeof(arr) not work consistently in C? In someFunction()
sizeof(arr) means sizeof(&arr[0]) in main. The compiler knows how big arr
is, so why the difference - esp. as it would be v.useful if sizeof(arr)
worked in someFunction as it does in main - so you could use sizeof(arr) in
the conditional bit of,say, a for loop in someFunction for example?

3. Why doesn't C allow testFunction to be declared char [] testFunction -
seems to me that if it did you could get away with knowing less about
pointers, and it seems as though again that C is incosistent, i.e., you
don't have to declare testFunction's parameter as char *. Surely, the
compiler should know that char [] someFunction actually means char *
someFunction??

char * testFunction(char []);

int main(void)
{
/* Lie to the compiler. Should be ok though as the compiler knows how
big the array really is.*/
char arr[7] = "0123456789";

/* Ouput the sizeof the array. And the size of a pointer to it. */
printf("main() sizeof arr = %d\n", sizeof(arr));
printf("main() sizeof arr = %d\n", sizeof(&arr[0]));

/* Pass it on to the function where we'll do some other emaningless
things.*/
testFunction(arr);
return 0;
}
/* Can't declare testFunction as char [] testF...() - even though the
compiler knows that array's are passed by address.*/

/* The size is ignored - and can't be checked anyway.*/
char * testFunction(char arr[500])
{
int n;

/* Same sizeof line of code that was in main() - note here that it
output the size of a pointer!*/
printf("sizeof arr = %d\n", sizeof(arr));

return arr;
}
Dec 17 '05 #1
Share this Question
Share on Google+
27 Replies


P: n/a
jimbo <ji***@gmail.com> wrote:
1. Are the comments in it correct?
You forgot the part about "Never do this."
2. Why does sizeof(arr) not work consistently in C?
Because it doesn't work the way you seem to think it does.
In someFunction()
sizeof(arr) means sizeof(&arr[0]) in main. The compiler knows how big arr
is, so why the difference - esp. as it would be v.useful if sizeof(arr)
worked in someFunction as it does in main - so you could use sizeof(arr) in
the conditional bit of,say, a for loop in someFunction for example?
Because the 500 in
char * testFunction(char arr[500])
is completely meaningless. arr is a pointer to a char; the compiler
has no idea how many it points to. That's your job.
3. Why doesn't C allow testFunction to be declared char [] testFunction -
Because char[] and char * are not the same. IIRC, char [] is an array
of pointers of unspecified size.
seems to me that if it did you could get away with knowing less about
pointers,


Thus further burying the secrets of how to use them correctly...

--
Christopher Benson-Manica | I *should* know what I'm talking about - if I
ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
Dec 17 '05 #2

P: n/a
On Sat, 17 Dec 2005 20:11:41 GMT, in comp.lang.c , "jimbo"
<ji***@gmail.com> wrote:
2. Why does sizeof(arr) not work consistently in C?
It does. Please read the documentation on it carefully, understand the
difrference between a pointer and an array, and understand what
happens to arrays when passed as parameters to functions.
/* Lie to the compiler. Should be ok though as the compiler knows how
big the array really is.*/
char arr[7] = "0123456789";


No, its disastrous. You just overwrote memory that doesn't belong to
you.

Never lie to the compiler. Like your grandmother, it will find you out
and beat you with a willow twig.

----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==----
http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
----= East and West-Coast Server Farms - Total Privacy via Encryption =----
Dec 17 '05 #3

P: n/a
jimbo a écrit :
Could someone comment on this code please.
First of all, you should learn to tune your compiler in a better way.

Compiling: main.c
main.c: In function `main_':
main.c:7: warning: initializer-string for array of chars is too long
main.c:10: error: implicit declaration of function `printf'
main.c:10: warning: nested extern declaration of `printf'
<internal>:0: warning: redundant redeclaration of 'printf'
main.c: In function `testFunction':
main.c:30: warning: nested extern declaration of `printf'
<internal>:0: warning: redundant redeclaration of 'printf'
main.c:26: warning: unused variable `n'
main.c:33:3: warning: no newline at end of file
Process terminated with status 1 (0 minutes, 0 seconds)
1 errors, 5 warnings
1. Are the comments in it correct?
/* -ed-
missing header for printf()
(a prototype in scope is mandatory for variadics functions)
*/
#include <stdio.h>

char * testFunction(char []);

int main(void)
{
/* Lie to the compiler. Should be ok though as the compiler knows how
big the array really is.*/
char arr[7] = "0123456789";

/* -ed- I have this (gcc/mingw):

main.c:19: warning: initializer-string for array of chars is too long

sounds enough to me.

On another compiler (BC 3.1), I have a compile error.
*/

/* Ouput the sizeof the array. And the size of a pointer to it. */
printf("main() sizeof arr = %d\n", sizeof(arr));
printf("main() sizeof arr = %d\n", sizeof(&arr[0]));

/* Pass it on to the function where we'll do some other emaningless
things.*/
testFunction(arr);
return 0;
}

/* Can't declare testFunction as char [] testF...() - even though the
compiler knows that array's are passed by address.*/
/* -ed- What's wrong with

char * testF...()

which is exactly the reflect of the truth ?
*/

/* The size is ignored - and can't be checked anyway.*/
/* -ed-
True. This is because of the type you used (pointer to an element).
Try 'pointer to an array' and it will be different. (But hard to
maintain).
The pointer to element way is simple and dynamic.
Just add a nb_of_elements parameter.
*/
char * testFunction(char arr[500])
{
int n;
/* -ed- never used...

main.c:38: warning: unused variable `n'

*/

/* Same sizeof line of code that was in main() - note here that it
output the size of a pointer!*/
printf("sizeof arr = %d\n", sizeof(arr));
/* -ed-
Undefined behaviour. sizeof returns a size_t. You want

printf("sizeof arr = %zu\n", sizeof(arr));

or

printf("sizeof arr = %lu\n", (unsigned long) sizeof arr);

but keep in mind that 'arr' is just another pointer.
You will have the sizeof a a pointer, not to the pointed array.
An extra parameter is required for that
(all the difference between gets() and fgets()).

Note that the parens are not required with objects.

*/
return arr;
}
2. Why does sizeof(arr) not work consistently in C?


It does. Just don't mix arrays and pointers.

--
A+

Emmanuel Delahaye
Dec 17 '05 #4

P: n/a
jimbo wrote:
Could someone comment on this code please.

1. Are the comments in it correct?

2. Why does sizeof(arr) not work consistently in C?
It *does* work consistently.
In someFunction()
sizeof(arr) means sizeof(&arr[0]) in main.
This is the problem, you haven't understood that you don't actually pass
the array (C is not Pascal) what you pass is a pointer to the first
element of the array. This is a FAQ, see
http://www.eskimo.com/~scs/C-faq/q6.21.html and
http://www.eskimo.com/~scs/C-faq/q6.21.html
The compiler knows how big arr
is, so why the difference - esp. as it would be v.useful if sizeof(arr)
worked in someFunction as it does in main - so you could use sizeof(arr) in
the conditional bit of,say, a for loop in someFunction for example?
It can't know in general, because you might write the function in one
translation unit and the, 25 years later, write another translation unit
that calls the first passing it an array of a different size.
3. Why doesn't C allow testFunction to be declared char [] testFunction -
Because that is the way it is defined.
seems to me that if it did you could get away with knowing less about
pointers,
For good or ill programming in C really requires an understanding of
pointers, because for the vast majority of non-trivial problems you will
end up using them.
and it seems as though again that C is incosistent, i.e., you
don't have to declare testFunction's parameter as char *. Surely, the
compiler should know that char [] someFunction actually means char *
someFunction??
If both were valid they would mean different things. One would mean
returning an array, which C does not allow, whilst the other does mean
returning a pointer to char.
char * testFunction(char []);

int main(void)
{
/* Lie to the compiler. Should be ok though as the compiler knows how
big the array really is.*/
char arr[7] = "0123456789";
Never lie to the compiler. It *will* get its revenge one day, possibly
by causing your application to fail miserable in front of a massive
potential customer causing your company not to get the contract it was
relying on, with the result of you being sacked for incompetence. In
this case I believe it is a constraint violation, because the standard says:
| No initializer shall attempt to provide a value for an object not
| contained within the entity being initialized.
So the compiler is *required* to complain at you, and if the compiler
chooses to produce an executable after complaining the program is
allowed to do anything at all since it is *not* a valid C program.
/* Ouput the sizeof the array. And the size of a pointer to it. */
printf("main() sizeof arr = %d\n", sizeof(arr));
If you are going to use printf you should include stdio.h because
varidac functions *require* a prototype to be in scope when you call
them or you invoke undefined behaviour and the program is allowed to do
anything at all. (you can provide a prototype manually, but that would
be a very stupid thing to do).
printf("main() sizeof arr = %d\n", sizeof(&arr[0]));

/* Pass it on to the function where we'll do some other emaningless
things.*/
testFunction(arr);
return 0;
}
/* Can't declare testFunction as char [] testF...() - even though the
compiler knows that array's are passed by address.*/
No, this is wrong. Arrays are not passed at all, a pointer to the first
element is passed.
/* The size is ignored - and can't be checked anyway.*/
char * testFunction(char arr[500])
{
int n;

/* Same sizeof line of code that was in main() - note here that it
output the size of a pointer!*/
printf("sizeof arr = %d\n", sizeof(arr));
That is because it *is* outputting the size of a pointer.
return arr;
Here you are *not* returning an array, you are returning a pointer.
}

--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
Dec 17 '05 #5

P: n/a
Flash Gordon a écrit :
Here you are *not* returning an array, you are returning a pointer.
}

Or more likely, an address...

--
A+

Emmanuel Delahaye
Dec 17 '05 #6

P: n/a
Emmanuel Delahaye wrote:
Flash Gordon a écrit :
Here you are *not* returning an array, you are returning a pointer.
}

Or more likely, an address...


The last time I looked the null pointer was not an address, although I
will happily accept correction if someone can point out something in the
standard that says otherwise. So I think it more accurate to talk of
returning a pointer than an address.
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
Dec 18 '05 #7

P: n/a
"jimbo" <ji***@gmail.com> writes:
Could someone comment on this code please.

1. Are the comments in it correct?

2. Why does sizeof(arr) not work consistently in C? In someFunction()
sizeof(arr) means sizeof(&arr[0]) in main. The compiler knows how big arr
is, so why the difference - esp. as it would be v.useful if sizeof(arr)
worked in someFunction as it does in main - so you could use sizeof(arr) in
the conditional bit of,say, a for loop in someFunction for example?

3. Why doesn't C allow testFunction to be declared char [] testFunction -
seems to me that if it did you could get away with knowing less about
pointers, and it seems as though again that C is incosistent, i.e., you
don't have to declare testFunction's parameter as char *. Surely, the
compiler should know that char [] someFunction actually means char *
someFunction??

char * testFunction(char []);

int main(void)
{
/* Lie to the compiler. Should be ok though as the compiler knows how
big the array really is.*/
char arr[7] = "0123456789";


What do you mean "should be ok"? To handle this, the compiler would
either have to make arr bigger than you asked, or ignore part of the
initializer; neither is a sensible thing to expect.

I'm not sure whether this is a constraint violation or undefined
behavior, but it's certainly a bad idea (as lying to the compiler
always is). Don't do that.

(If the initializer were too short, the remaining elements would be
initialized to zero.)

As for the rest of your questions, C's treatment of arrays and
pointers is actually (mostly) consistent, though it can be confusing.
Section 6 of the comp.lang.c FAQ has a lot of good information; you
can find it at <http://www.eskimo.com/~scs/C-faq/top.html>.

To summarize:

Arrays are arrays. Pointers are pointers. Arrays are not pointers.
Pointers are not arrays. Anyone who tells you otherwise is mistaken.

An expression of array type, in most contexts, is implicitly converted
to a pointer to the array's first element; this conversion does not
happen for the operand of a unary "&" or "sizeof" operator, or for a
string literal used to initialize an array. (Thus you can initialize
an array object with a string literal, but you can't *assign* a string
literal to an array object.)

As a special case, a parameter declaration such as
void func(SOME_TYPE *param);
can be written as
void func(SOME_TYPE param[]);
These are equivalent; the latter really declares a pointer, not an
array. This makes it slightly easier to ignore the distinction
between pointers and arrays. In my opinion, it was a mistake to have
this feature in the language. This equivalence applies only to
function parameters; in particular, it does not apply to function
return types. (It's been argued that the param[] form is useful to
document the intent that the argument should be an array, but the
compiler doesn't check this. If you want to document something that
the compiler can't check, you can use a comment.)

The indexing operator x[y], takes two operands, a pointer and an
integer (*not* an array and an integer). Typically, the pointer
operand is going to be an array name, which will be implicitly
converted to a pointer before the indexing operator sees its value.
x[y] is by definition equivalent to *(x+y). (Because addition is
commutative, x[y] can be written as [y]x; this odd little quirk is in
no way useful.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Dec 18 '05 #8

P: n/a
Christopher Benson-Manica wrote:
jimbo <ji***@gmail.com> wrote:
3. Why doesn't C allow testFunction to be declared char [] testFunction -

Because char[] and char * are not the same. IIRC, char [] is an array
of pointers of unspecified size.


You remember incorrectly. In the parameter list of a function, char[]
and char* are exactly the same. In any other declaration they are
different. char[] is never an array of pointers. It can represent an
array of char, of unspecified size. If an initialiser is provided, it
represents an array of char, of the size required to contain the
initialiser. For example,

$ cat foo.c

#include <stdio.h>

/*
The following line declares an array of char of unspecified size. It
is OK to use this array, but not to ask the compiler about its size
within this translation unit.
*/
extern char bar[];

void print_bar(void)
{
puts(bar);
}

$ cat bar.c

/*
The following line defines an array of char whose size is inferred
from the initialiser given, so it will be 13 chars long. It is OK
to both use this array and ask the compiler about its size within
this translation unit.
*/
char bar[] = "hello, world";

void print_bar(void);

int main(void)
{
print_bar();
return 0;
}

$ c99 -pedantic -Wall -W -O2 -c foo.c
$ c99 -pedantic -Wall -W -O2 -c bar.c
$ c99 foo.o bar.o -o foobar
$ ./foobar
hello, world

--
Simon.
Dec 18 '05 #9

P: n/a
Emmanuel Delahaye <em***@YOURBRAnoos.fr> writes:
Flash Gordon a écrit :
Here you are *not* returning an array, you are returning a pointer.
}

Or more likely, an address...


Is this the old argument about the meanings of the terms "pointer" and
"address"?

It's reasonable, IMHO, to use the term "pointer" only to refer to an
object of pointer type, and the term "address" to refer to a *value*
of pointer type. Thus the value of a pointer object is an address. I
generally try to use the terms this way myself.

But the standard doesn't make this distinction, at least not
consistently. For example, the malloc() function "returns either a
null pointer or a pointer to the allocated space".

I think we have to accept that referring to a pointer value, such as
"returning a pointer", is acceptable.

If that wasn't your point, wha was?

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Dec 18 '05 #10

P: n/a
Mark McIntyre wrote:
On Sat, 17 Dec 2005 20:11:41 GMT, in comp.lang.c , "jimbo"
<ji***@gmail.com> wrote:

2. Why does sizeof(arr) not work consistently in C?

It does. Please read the documentation on it carefully, understand the
difrference between a pointer and an array, and understand what
happens to arrays when passed as parameters to functions.

/* Lie to the compiler. Should be ok though as the compiler knows how
big the array really is.*/
char arr[7] = "0123456789";

No, its disastrous. You just overwrote memory that doesn't belong to
you.


Any compiler worth its salt will diagnose that error at compile time,
and so you will fix the problem, and never get to the stage of actually
overwriting memory.

In fact, it is a constraint, and as such must be diagnosed by a
standard-conforming C compiler:

6.7.8 Initialization
...
Constraints
2 No initializer shall attempt to provide a value for an object not
contained within the entity being initialized.

--
Simon.
Dec 18 '05 #11

P: n/a
On Sat, 17 Dec 2005 21:54:50 +0000, Mark McIntyre
<ma**********@spamcop.net> wrote:
On Sat, 17 Dec 2005 20:11:41 GMT, in comp.lang.c , "jimbo"
<ji***@gmail.com> wrote:
2. Why does sizeof(arr) not work consistently in C?


It does. Please read the documentation on it carefully, understand the
difrference between a pointer and an array, and understand what
happens to arrays when passed as parameters to functions.
/* Lie to the compiler. Should be ok though as the compiler knows how
big the array really is.*/
char arr[7] = "0123456789";


No, its disastrous. You just overwrote memory that doesn't belong to
you.


Isn't this simply a constraint violation (6.7.8-2) that requires a
diagnostic? Do any existing compilers actually initialize more than
the 7 bytes defined?
<<Remove the del for email>>
Dec 18 '05 #12

P: n/a
Simon Biber <ne**@ralmin.cc> wrote:
You remember incorrectly. In the parameter list of a function, char[]
and char* are exactly the same. In any other declaration they are
different. char[] is never an array of pointers. It can represent an
array of char, of unspecified size.


That is what I meant to say; the fact that I did not is disturbing. I
appreciate the correction.

--
Christopher Benson-Manica | I *should* know what I'm talking about - if I
ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
Dec 18 '05 #13

P: n/a
"Keith Thompson" <ks***@mib.org> wrote in message
news:ln************@nuthaus.mib.org...
The indexing operator x[y], takes two operands, a pointer and an
integer (*not* an array and an integer). Typically, the pointer
operand is going to be an array name, which will be implicitly
converted to a pointer before the indexing operator sees its value.
x[y] is by definition equivalent to *(x+y). (Because addition is
commutative, x[y] can be written as [y]x; this odd little quirk is in
no way useful.) ^^^^


ITYM "x[y] can be written as y[x]". For example, "123"[1] is equivalent to
1["123"], but [1]"123" is a syntax error.
Dec 18 '05 #14

P: n/a
Keith Thompson a écrit :
Here you are *not* returning an array, you are returning a pointer.
Or more likely, an address...
Is this the old argument about the meanings of the terms "pointer" and
"address"?


Yes. Based on the fact that a pointer is an variable whose value is an
address, an address itself is a pointer constant. It's also the value of
a pointer. (like 123 is an integer constant and also the value of
variable of type char or int etc.)
It's reasonable, IMHO, to use the term "pointer" only to refer to an
object of pointer type, and the term "address" to refer to a *value*
of pointer type.
I'm glad to read that.
Thus the value of a pointer object is an address. I
generally try to use the terms this way myself.

But the standard doesn't make this distinction, at least not
consistently. For example, the malloc() function "returns either a
null pointer or a pointer to the allocated space".
Too bad and confusing. I would have written it like this:

<<the malloc() function "returns either a null pointer constant or the
address of the allocated space">>

Of course, it is useful to store this address into a pointer. Once
stored, the pointer points to the allocated block.

Simple wording, simple meaning, no trick... I understand better why
people have hard time with pointers. Seems obvious that the semantic
around'em isn't clear and consistent enough.
I think we have to accept that referring to a pointer value, such as
"returning a pointer", is acceptable.


Unfortunately, yes.

--
A+

Emmanuel Delahaye
Dec 18 '05 #15

P: n/a
Flash Gordon a écrit :
Emmanuel Delahaye wrote:
Flash Gordon a écrit :
Here you are *not* returning an array, you are returning a pointer.

}
Or more likely, an address...

The last time I looked the null pointer was not an address,


There is no 'null pointer'. There is a 'null pointer constant' also
known as NULL.

Ok, I should have written :

<<Or more likely, an address the null pointer constant aka NULL>>

although I
will happily accept correction if someone can point out something in the
standard that says otherwise. So I think it more accurate to talk of
returning a pointer than an address.


See Keith's response and my response to him.

--
A+

Emmanuel Delahaye
Dec 18 '05 #16

P: n/a

"Flash Gordon" <sp**@flash-gordon.me.uk> wrote in message
news:1a************@news.flash-gordon.me.uk...
jimbo wrote: <snip>
and it seems as though again that C is incosistent, i.e., you
don't have to declare testFunction's parameter as char *. Surely, the
compiler should know that char [] someFunction actually means char *
someFunction??


If both were valid they would mean different things. One would mean
returning an array, which C does not allow, whilst the other does mean
returning a pointer to char.


"If both were valid they would mean different things"

Hmmmm

Suerly, there is an inconsistency here with char ?[]

If

char * someFunction(char arr[])

Can also be written [and has the same meaning as]

char * someFunction(char * arr)

Then we can interpret char arr[] as a parameter type as *NOT* meaning that
an array is passed. E.g., both of these *are* valid, and they both mean
*the same thing*. So "If both were valid they would mean different things"
is not necessarily a good argument against not allowing this as a return
type IMHO.

Why not interpret - consistently with this in a
function-definition/declaration sense - char [] someFun.... as *NOT* meaning
that an array is returned then?

Also, as using char [] as a return type will cause a compiler error, in the
future, its meaning could be 'aligned' with its use when used as a parameter
without breaking any 'old' code. IMHO, this would be a useful semantic
alignment to make.

Dec 18 '05 #17

P: n/a

"Simon Biber" <ne**@ralmin.cc> wrote in message
news:43***********************@news.optusnet.com.a u...
Christopher Benson-Manica wrote:

Because char[] and char * are not the same. IIRC, char [] is an array
of pointers of unspecified size.


You remember incorrectly. In the parameter list of a function, char[] and
char* are exactly the same. In any other declaration they are different.


I think this is the OP's point - please see my other post re its use as a
return type.
Dec 18 '05 #18

P: n/a
Emmanuel Delahaye wrote:
Keith Thompson a écrit :
Here you are *not* returning an array, you are returning a pointer. Or more likely, an address...
Is this the old argument about the meanings of the terms "pointer" and
"address"?


Yes. Based on the fact that a pointer is an variable whose value is an
address, an address itself is a pointer constant. It's also the value of
a pointer. (like 123 is an integer constant and also the value of
variable of type char or int etc.)


The problems I see with the term address are:
1) If you talk about returning an address you either imply that a null
pointer constant is an address leading to confusion about what you
can do with it, or continually say "address or null pointer" (or
something similar.
2) You are likely to confuse people about what they cad do. IMHO that
since address is a term used when talking about the hardware where no
type is involved (it is just memory), where as pointers are not.

After all, in summary, C pointers are slightly more abstract than
machine addresses.

<snip>
<<the malloc() function "returns either a null pointer constant or the
address of the allocated space">>

Of course, it is useful to store this address into a pointer. Once
stored, the pointer points to the allocated block.
I think it would be simpler if pointer or pointer value was used
throughout, see above. Just as I would refer to an int being returned by
a function.
Simple wording, simple meaning, no trick... I understand better why
people have hard time with pointers. Seems obvious that the semantic
around'em isn't clear and consistent enough.


Agreed. It would be better if consisten terminology is used.
I think we have to accept that referring to a pointer value, such as
"returning a pointer", is acceptable.


Unfortunately, yes.


I think it would be better if the term "address" was not used, expect
when talking about how pointers are implemented and possibly talking
about converting between pointer types. However, I recognise this is
very much my personal opinion, and I have no authority to call on, so
I'm certainly not going to complain about people talking about
addresses. I certainly see no point to a long discussion on this subject.
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
Dec 18 '05 #19

P: n/a
Flash Gordon a écrit :
The problems I see with the term address are: <...> After all, in summary, C pointers are slightly more abstract than
machine addresses. <...> I think it would be better if the term "address" was not used, expect


May be the good wording should be 'reference' ?

"A reference is a (unique ?) value that identifies the memory location
of an object."

"NULL is a reference constant meaning invalid reference."

"A pointer is a variable that holds a reference to an object or NULL."
or:
"A pointer is a variable that holds the reference of an object or NULL."

"When a pointer is typed, the dereference operator (*) allows a read of
write acces to the referenced object."

etc. I'm not going to rewrite the C-standard, but I think that this kind
of wording could be used in C-books and tutorials for consistency.

--
A+

Emmanuel Delahaye
Dec 18 '05 #20

P: n/a
Emmanuel Delahaye wrote:
Flash Gordon a écrit :
Emmanuel Delahaye wrote:
Flash Gordon a écrit :

Here you are *not* returning an array, you are returning a pointer.

> }

Or more likely, an address...

The last time I looked the null pointer was not an address,


There is no 'null pointer'.


The C standard refers to "a null pointer" in serveral places. Such as,
in n1124.pdf, section 5.1.2.2.1 Program startup, "argv[argc] shall be a
null pointer.", a good one is section 6.3.2.3 Pointers where it says:
| 3 An integer constant expression with the value 0, or such an
| expression cast to type void *, is called a null pointer
| constant.55) If a null pointer constant is converted to a pointer
| type, the resulting pointer, called a null pointer, is guaranteed to
^^^^^^^^^^^^^^^^^^^^^
| compare unequal to a pointer to any object or function.

I think it is fair to say that if the standard says that is a null
pointer constant is converted to a pointer type the resulting pointer is
called a null pointer that null pointers definitely do exist according
to the standard.

There are also many other references to 'null pointer' as opposed to
'null pointer constant' in the standard, and I can't believe that all of
them where added after the C89 standard.
There is a 'null pointer constant' also
known as NULL.
No, NULL is a macro that expands to a null pointer constant, and the
last time I checked 0 was not known as NULL, although it is most
definitely a null pointer constant.
Ok, I should have written :

<<Or more likely, an address the null pointer constant aka NULL>>

although I will happily accept correction if someone can point out
something in the standard that says otherwise. So I think it more
accurate to talk of returning a pointer than an address.


See Keith's response and my response to him.


I don't see that those responses prove me wrong. See my reply to them.
In addition, in n1124, section 7.20.3.3 The malloc function it says:
| 3 The malloc function returns either a null pointer or a pointer to
| the allocated space.

If the *standard* talks about a standard library function returning a
pointer then as far as I can see it *must* be valid to talk about
functions returning pointers. Or are you saying that if I write a function:
#include <stdlib.h>
void *my_malloc(size_t s)
{
return malloc(s);
}
That is somehow mysteriously stops being a pointer after malloc has
returned it just because it is my function returning it?
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
Dec 18 '05 #21

P: n/a
pemo wrote:
"Flash Gordon" <sp**@flash-gordon.me.uk> wrote in message
news:1a************@news.flash-gordon.me.uk...
jimbo wrote:

<snip>
and it seems as though again that C is incosistent, i.e., you
don't have to declare testFunction's parameter as char *. Surely, the
compiler should know that char [] someFunction actually means char *
someFunction??

If both were valid they would mean different things. One would mean
returning an array, which C does not allow, whilst the other does mean
returning a pointer to char.


"If both were valid they would mean different things"

Hmmmm

Suerly, there is an inconsistency here with char ?[]


OK, I'll admit the standard is inconsistent and that it *could* define s
function returning char [] as being the same one returning char *, i.e. make
char []func(void);
and
char *func(void);
the same.

My opinion is that this would only add to the confusion. A reason for
not allowing it is because:

char *pointless_func(char derf[])
{
return derf;
}

int main(void)
{
char fred[20] = "char array";
char another_array[20];
char *ptr;
ptr = pointless_func(fred); /* this is legal */
another_array = pointless_func(fred); /* this is illegal */
}

The first is an example where usage looks like definition, because the
definition looks like it takes an array, and that is probably why "char
derf[]" is allowed. The second would be usage looking like definition if
char []pointless_func(char derf[])
{
return derf;
}
was allowed, but the usage would still not be allowed.

So a parameter of char[] means you can pass a char array to the function.
For a return type of char[] to mean you could assign it to an array (the
obvious usage) it would mean it would require different semantics to a
return type of char*.
So my opinion is that it would just add further to the confusion.
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
Dec 18 '05 #22

P: n/a
Emmanuel Delahaye wrote:
Flash Gordon a écrit :
The problems I see with the term address are:

<...>
After all, in summary, C pointers are slightly more abstract than
machine addresses.

<...>
I think it would be better if the term "address" was not used, expect


May be the good wording should be 'reference' ?


<snip examples>

The problem with that is that I believe that other languages have used
the term "reference" to mean something else, so you would confuse people
coming from such a language to C or going from C to such a language.

I really don't see the problem with referring to a function returning a
pointer, or if you want to avoid confusion with pointer variables then
talking about 'pointer values'. IMHO it keeps it clearly tied to the
pointer type, and I consider that to be a good thing.

As I say, I'm not going to object to others using the word address,
after all the standard refers to, "the result points to the lowest
addressed byte of the object." when talking about converting to a char
pointer and you have the "address operator" etc.
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
Dec 18 '05 #23

P: n/a
"buda" <ku*****@hotmail.com> writes:
"Keith Thompson" <ks***@mib.org> wrote in message
news:ln************@nuthaus.mib.org...
The indexing operator x[y], takes two operands, a pointer and an
integer (*not* an array and an integer). Typically, the pointer
operand is going to be an array name, which will be implicitly
converted to a pointer before the indexing operator sees its value.
x[y] is by definition equivalent to *(x+y). (Because addition is
commutative, x[y] can be written as [y]x; this odd little quirk is in
no way useful.) ^^^^


ITYM "x[y] can be written as y[x]". For example, "123"[1] is equivalent to
1["123"], but [1]"123" is a syntax error.


Yes, that's what I meant. Thanks for the correction.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Dec 18 '05 #24

P: n/a
Emmanuel Delahaye <em***@YOURBRAnoos.fr> writes:
Flash Gordon a écrit :
The problems I see with the term address are:

<...>
After all, in summary, C pointers are slightly more abstract than
machine addresses.

<...>
I think it would be better if the term "address" was not used, expect


May be the good wording should be 'reference' ?

"A reference is a (unique ?) value that identifies the memory location
of an object."

[snip]

C++ has things it calls references, and they're not pointers or
addresses.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Dec 18 '05 #25

P: n/a
Emmanuel Delahaye <em***@YOURBRAnoos.fr> writes:
Flash Gordon a écrit :
Emmanuel Delahaye wrote:
Flash Gordon a écrit :

Here you are *not* returning an array, you are returning a pointer.

> }

Or more likely, an address...

The last time I looked the null pointer was not an address,


There is no 'null pointer'. There is a 'null pointer constant' also
known as NULL.


Sorry, but there are at least two major errors there.

There most certainly is a null pointer. It's defined in C99
6.3.2.3p3; Flash Gordon quoted the definition in another response.
(The term "null pointer" is in italics, so that's *the* definition of
the term.)

A null pointer constant is not "also known as" NULL. A null pointer
constant is a syntactic construct (also defined in 6.3.2.3p3), which
occurs only in source code. NULL is a macro that expands to some
specific implementation-defined null pointer constant. A null pointer
is a value that exists at run time. (It can result from things other
than a null pointer constant, which means the standard's definition of
"null pointer" is incomplete.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Dec 18 '05 #26

P: n/a
Flash Gordon wrote:

OK, I'll admit the standard is inconsistent and that it *could*
define s function returning char [] as being the same one
returning char *, i.e. make
char []func(void);
and
char *func(void);
the same.
That's not how array declarations work in C:
char x[9]; /* correct */
char[9] x; /* wrong */

The syntax for a function returning an array of char would be:
char func(void) [];

(but the C standard explicitly says that returning an array is
illegal).
pemo wrote:
Suerly, there is an inconsistency here with char ?[]


Two wrongs don't make a right -- it would have been
better if the [] syntax in function parameters were
never permitted.

Dec 18 '05 #27

P: n/a
Flash Gordon <sp**@flash-gordon.me.uk> writes:
Emmanuel Delahaye wrote:
Keith Thompson a écrit :
> Here you are *not* returning an array, you are returning a pointer.

Or more likely, an address...

Is this the old argument about the meanings of the terms "pointer" and
"address"?


Yes. Based on the fact that a pointer is an variable whose value is an
address, an address itself is a pointer constant. It's also the value of
a pointer. (like 123 is an integer constant and also the value of
variable of type char or int etc.)


The problems I see with the term address are:
1) If you talk about returning an address you either imply that a null
pointer constant is an address leading to confusion about what you
can do with it, or continually say "address or null pointer" (or
something similar.
2) You are likely to confuse people about what they cad do. IMHO that
since address is a term used when talking about the hardware where no
type is involved (it is just memory), where as pointers are not.

After all, in summary, C pointers are slightly more abstract than
machine addresses.


A pointer holding a null pointer value still holds an address. That
the address might not refer to any actual memory location, or might
not be usable to access memory (because of memory protection, etc),
doesn't make it not an address. There are machine architectures with
each of these properties.

I realize that the comments above just represent a point of view and
can't be called "right" or "wrong" (at least, not by reasonable
persons :). However, that view is one I was used to even before
learning C, and it simplifies the discussion and understanding of C,
so I think it's worth promulgating. Pointer values in C correspond
pretty well to the notion of "address", considered in a broad context
of various machine architectures. IMO, anyway.
Dec 28 '05 #28

This discussion thread is closed

Replies have been disabled for this discussion.