Ok, I was trying to show the point not sintaxis.
Try this:
int my_fync(int *piA)
{
printf("Arg: %u\n",piA);
return 0;
}
main ()
{
int a[10];
my_func((int*)c);
my_func((int*)&c);
return 0;
}
In both cases argument Arg: .... will be the same!!!
I skip casting, because I was talking about values. Yes in first case compiler will show WARNING because of wrong type,
but it will work.
Now about extra "*".
int my_fync(int **piA)
{
printf("Arg: %u\n",*piA); /* print "Arg: 1" */
printf("Arg: %u\n",(*piA)[0]); /* crush */
return 0;
}
main ()
{
int a[2] = {1,2};
my_func((int**)&c);
return 0;
}
May be I was not clear first time.
But I was right
main()
{
int a[10];
if (a == &a)
printf("It works\n"
else
printf("It doesn't \n"
}
Will show warning about incompatible type during compilation, BUT executable will print:
It works
> Ok, I was trying to show the point not sintaxis.
If you're trying to make a point about a programming language issue in which syntax is the central issue, I don't see the sense in a statement like that.
Yes, despite the warning about incompatible types they do seem to produce the same values in the function argument. Not being an expert on the C standard, I'd be interested to know if this is really legal or if it just /happens/ to work. In other words, just because it compiles and produces the expected result on a compiler doesn't mean it's correct. When you get warnings such as you get when you try to do my_func(&a) (passing arg 1 of 'myfunc' from incompatible pointer type), it's nearly always best to listen and get rid of that warning (and /not/ with a cast). At any rate, you can have that one
This causes all kinds of problems because you're passing an incompatible pointer type to my_func(). That cast just silences the compiler as you are in effect telling it, "Yes, I know that I'm not passing a pointer to a pointer to int to my_func(), but I know what I'm doing." Very rarely are casts justified and usually result in a covered up bug.
At any rate, how does this address the question I asked you in regard to the function knowing or caring about how the caller passes it arguments? As far as the function is concerned, it has a pointer to a pointer to int, it's implementation isn't affected whatsoever by how a caller passes arguments to it.
Below is an example using myfunc() with a pointer to pointer int and using the & operator in the caller. Note that you need to use the & operator to pass the function the correct type as it needs a deep copy of the pointer to affect the caller's copy:
#include <stdio.h>
#include <stdlib.h>
int my_func(int **piA,int count)
{
int i;
*piA=malloc(count);
if (NULL!=piA) {
for (i=0;i<count;++i) {
/* No crush here! */
(*piA)=i+1;
}
return 0;
} else {
return 1;
}
}
int main (void)
{
int *a;
int i;
int count=10;
if (0==my_func(&a,count)) {
for (i=0;i<count;++i) {
printf("%d\n",a);
}
free(a);
}
return 0;
}
The whole point of your post was to discourage people from using the address operator in situations where using the variable by itself and the variable prefixed with the address operator are equivalent -- you still haven't (IMO) made a convincing argument for this whatsoever.
>Yes, despite the warning about incompatible types they do >seem to produce the same values in the function argument. >Not being an expert on the C standard, I'd be interested >to know if this is really legal or if it just /happens/ to >work.
It is just how it works. (ANSI C standard 6.2.2.1). Yes compiler showing a warning in some cases,
but there are cases when compiler will not show the warning, but value will be the same. And if you don't understand how this work, this can cost you.
For example:
Some function (read_data()) read some data of different type from file.
This function dosn't know what type it is, it just calls other function which knows and pass to correct function argument that user send to this function as (void**).
read_int_array(int ** ppiData)
{
if (*ppiData == NULL) /* allocate if pointer is NULL */
*ppiData = malloc(10 * sizeof(int));
/* read into array */
............
}
read_data(void** ppvData)
{
switch (check_type())
{
case 1:
read_int_array((int**)ppvData);
break;
case 2:
read_double_array ((double**)ppvData);
break;
........
}
}
In this case when I whant to read some data into two
integer arrays one in dynamic memory, there other in stack:
main()
{
int *piData = NULL;
int aiData[10];
int *piTmp = NULL;
/* in first case */
read_data((void**)&piData);
/* will work fine (your example) */
/* but in second */
read_data ((void**)&aiData);
/* will lead to crush without any compiler warning! */
/* to read in this array you have to do next */
piTmp = aiData;
read_data ((void**)&piTmp);
/* this will work */
}
AND THIS WAS MY POINT!
Actually this was a bug in my program.
Again my point was in the differnce between:
int a[10];
int *b;
a - single pointer
&a - still a single pointer
b - single pointer
&b - pointer to the pointer
and how you can correctly use both arrays.
Yes, in this situation it's innappropriate to use the & operator because it fools the compiler into thinking that aiData is of the appropriate type. Doing this reflects a basic misunderstanding of pointers and arrays -- someone that understands this issue would never do something like that anyway. Therefore, I wouldn't encourage the person to stop using the & operator in passing arrays to functions (see my post in the char[][] char ** thread for an example of where using the & operator makes sense in passing an array to a function), but rather understand pointers and arrays and it will never occur to you to do something like the above. Just telling someone not to use the & operator to save them from making mistakes like the above doesn't really help.
>AND THIS WAS MY POINT!
>Actually this was a bug in my program.
>
>Again my point was in the differnce between:
>int a[10];
>int *b;
>a - single pointer
>&a - still a single pointer
>b - single pointer
>&b - pointer to the pointer
Ok...
>and how you can correctly use both arrays.
No, not correctly -- a compiler not complaining doesn't make it correct (see above).
>Don't use extra "&" for stack arrays.
>
>int a[10];
>a == &a;
>and
>my_func(a);
>is the same as
>my_func(&a);
This is what you originally posted. If the point you were trying to make was:
Don't use the & operator for arrays when passing them to functions that expect a pointer to a pointer because it will silence the compiler in these situations.
Your original post reads something like this:
NEVER use the & operator for arrays when passing them to functions.
See the difference?
BTW, which standard are you referring to? I just have a copy of C99 and this section reads:
6.2.2 Linkages of identifiers
1 An identifier declared in different scopes or in the same scope more than once can be
made to refer to the same object or function by a process called linkage.21) There are
three kinds of linkage: external, internal, and none.
First I have never told
"NEVER use the & operator for arrays when passing them to functions."
I have told:
"STOP adding extra "&" to stack arrays!!!"
By stack arrays I mean this: int iA[10]; not int *piA;
This what "yaronb" wrote:
"execvp(&foo[0],&foo)...
so &foo doesn't have sense, may be because of that his program doesn't work.
I am not crazy to tell do not use double pointer.
And about 6.2.2.1
I am tolking about ANSI/ISO 9899-1990
6.2.2 Other operands
6.2.2.1
.....
Except when it is the operator of the sizeof operator or the unary & operator, ....
an lvalue that has type "array of type" is converted to an expression that has type "pointer to type" that points to the initial element of the array object and is not an lvalue.
......
>Don't use extra "&" for stack arrays.
>
>int a[10];
>a == &a;
>and
>my_func(a);
>is the same as
>my_func(&a);
No, you did not use the word "never," but you didn't leave any room for exceptions, therefore that's how it reads.
>This what "yaronb" wrote:
>"execvp(&foo[0],&foo)...
I was talking about this thread, not the thread this line occurs in. People reading this haven't necessarily read the thread you're referring to.
No, you're not *crazy* to tell people not to use the & operator when passing an array to a function, given a certain context. Simply saying "Don't use extra "&" for stack arrays" doesn't provide that context.
This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
By continuing to use this site, you are consenting to our use of cookies.