Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
494 views
in Technique[技术] by (71.8m points)

c - Argument conversion: (normal) pointer to void pointer, cast needed?

When assigning to or from a void-pointer no cast is needed (C99 §6.3.2.2 sub 1 / §6.5.16.1 sub 1). Is this also true when passing a (for example int-)pointer to a function that expects a void-pointer?

For example:

void foo(void * p){
    // Do something
}

int main(){
    int i = 12;
    foo(&i); // int * to void *: no cast needed?
}

When I compile this with GCC (4.8.1, MinGW-32) I get neither errors nor warnings (with -Wall & -pedantic).

In contrast in this answer it is suggested that a cast is needed for this call (to eliminate -Wformat warnings):

int main(){
    int i = 12;
    printf("%p
", &i);
}

But in my case GCC doesn't complain.

So: are casts needed when passing a non-void-pointer to a function that expects a void-pointer?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The difference is printf is a variadic function and variadic functions follow different conversion rules on their trailing arguments.

foo(&i); 

no cast is needed here as foo is a prototyped function. C says &i is converted to the type of p as if by assignment and in C there is an implicit between all object pointer types to void *.

The case with printf is different as variadic functions like printf have default argument promotions on their remaining arguments and no conversion occur on the argument of pointer types.

C on prototyped functions:

(C99, 6.5.2.2p7) "If the expression that denotes the called function has a type that does include a prototype, the arguments are implicitly converted, as if by assignment, to the types of the corresponding parameters, taking the type of each parameter to be the unqualified version of its declared type."

C on variadic functions:

(C99, 6.5.2.2p7) "(C99, 6.5.2.2p7) "The ellipsis notation in a function prototype declarator causes argument type conversion to stop after the last declared parameter. The default argument promotions are performed on trailing arguments."

So: are casts needed when passing a non-void-pointer to a function that expects a void-pointer?

For printf, p conversion specifier requires a void * argument. If the argument is of a different type, the function call invokes undefined behavior. So if the argument of p is an object pointer type, the (void *) cast is required.

(C99, 7.19.6.1p8) "p The argument shall be a pointer to void."


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...