Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implications of typedef void FOO vs. #define FOO void in function signatures [duplicate]

While going through some source code that heavily mixes C and C++, I came across the following (slightly modified to protect the work of the company, the meaning remains the same):

/*
 * Typedefs of void are synonymous with the void keyword in C,
 * but not in C++. In order to support the use of MY_VOID
 * in place of the void keyword to specify that a function takes no
 * arguments, it must be a macro rather than a typedef.
 */
#define MY_VOID void

What is the difference between typedef void MY_VOID and #define MY_VOID void in this specific context?


I don't believe this is a duplicate of this question because it asks specifically about the implications in regards to function signatures, rather than a much more general "what's the difference".

like image 667
OMGtechy Avatar asked Apr 27 '15 12:04

OMGtechy


People also ask

What is the difference between void foo void and void foo ()?

void foo() means "a function foo taking an unspecified number of arguments of unspecified type" void foo(void) means "a function foo taking no arguments"

What does the declaration void * foo () mean?

As a return “type”. In the function declaration void foo(int) , the void signifies that “ foo does not return a value”. As a parameter type list.

What is void (* foo )( int );?

1. void (*foo)( int ); In this example, foo is a pointer to a function taking one argument, an integer, and that returns void. It's as if you're declaring a function called "*foo", which takes an int and returns void; now, if *foo is a function, then foo must be a pointer to a function.

What is typedef void?

typedef void (*MCB)(void); This is one of the areas where there is a significant difference between C, which does not - yet - require all functions to be prototyped before being defined or used, and C++, which does.


2 Answers

A simple test program in C++ demonstrates the difference:

typedef void VOID;

void f(VOID) {}

int main()
{
    f();
}

On compilation (as C++), it gives these error:

prog.cpp:5:8: error: '<anonymous>' has incomplete type
 void f(VOID) {}
        ^
prog.cpp:5:12: error: invalid use of 'VOID {aka void}'
 void f(VOID) {}
            ^
prog.cpp: In function 'int main()':
prog.cpp:9:7: error: too few arguments to function 'void f(<type error>)'
     f();
       ^
prog.cpp:5:6: note: declared here
 void f(VOID) {}
      ^

which explains what the comment means in your code. In particular, it seems the typedef VOID attempts to be a type different from void, when it is used as parameter type.

like image 175
Nawaz Avatar answered Oct 05 '22 21:10

Nawaz


The comment explains the difference. Given an alias for void:

typedef void MY_VOID;

If you try to use this instead of void to indicate that a function takes no parameters:

int f(MY_VOID);

C will allow this, but C++ won't.

So, if you really want to make life difficult for yourself by writing code that (a) is valid in both languages and (b) uses an alias for this particular use of void, that alias will have to be a macro.

like image 33
Mike Seymour Avatar answered Oct 05 '22 21:10

Mike Seymour