Jump to content


void as a function parameter


116 replies to this topic

#1 poita

    Senior Member

  • Members
  • PipPipPipPip
  • 322 posts

Posted 27 May 2006 - 09:34 AM

Is there any difference between:

int myFunc() {...}

and

int myFunc(void) {...}

?

I've always assumed that there is no difference but now I'm wondering why people would even bother using the second one.

Thanks in advance

#2 Jare

    Valued Member

  • Members
  • PipPipPip
  • 247 posts

Posted 27 May 2006 - 10:05 AM

Old habits die hard. They are identical in C++.

#3 kusma

    Valued Member

  • Members
  • PipPipPip
  • 163 posts

Posted 27 May 2006 - 10:32 AM

poita: some compilers complain if you don't use void in c-code.

#4 Ed Mack

    Senior Member

  • Members
  • PipPipPipPip
  • 1239 posts

Posted 27 May 2006 - 10:33 AM

int myFunc() {...} is generally considered better form in C++ :)

#5 bramz

    Valued Member

  • Members
  • PipPipPip
  • 189 posts

Posted 27 May 2006 - 10:38 AM

poita said:

I've always assumed that there is no difference but now I'm wondering why people would even bother using the second one.

Because it looks complicated ...

In short: don't bother.
hi, i'm a signature viruz, plz set me as your signature and help me spread :)
Bramz' warehouse | LiAR isn't a raytracer

#6 roel

    Senior Member

  • Members
  • PipPipPipPip
  • 698 posts

Posted 27 May 2006 - 10:51 AM

well, bother if it is likely that your code gets compiled on an old C compiler.

#7 Nick

    Senior Member

  • Members
  • PipPipPipPip
  • 1227 posts
  • LocationOttawa, Ontario, Canada

Posted 27 May 2006 - 11:55 AM

The problem with void as a parameter is that it's not a parameter.

Ok this requires some illustration. You can't write code like this:

void function(int x, void y, int z)

{

    // ...

}

It serves no purpose whatsoever and just like you'd have to remove 'void y' from the above example, it's best not to write void for a completely empty parameter list.

Unfortunately C++ isn't consistent with that for functions. You can't omit the void in front of the function in the example above. Yet it would be completely unambiguous and safe as long as the compiler would enforce that you can't return any value from such function. Note by the way that we don't write 'return void' either.

#8 .oisyn

    DevMaster Staff

  • Moderators
  • 1842 posts

Posted 27 May 2006 - 01:28 PM

The difference in C is that with (void), you're specifying that it has no parameters, while with () you're specifying that the parameters are unspecified unless it is not a functiondeclaration but a functiondefinition, in which case it's the same as (void). Talking about consistency :). (Note that this is also different from (...), which means it can be called with any number and types of arguments). Of course the () in function declarations doesn't behave in C++ as in C because of function overloads and all, plus the fact that it isn't very type-safe.

Nick said:

Unfortunately C++ isn't consistent with that for functions. You can't omit the void in front of the function in the example above. Yet it would be completely unambiguous and safe as long as the compiler would enforce that you can't return any value from such function.

In fact it is ambiguous.
int main()
{
    bla(); // a function declaration or a function call expression?
}

Quote

Note by the way that we don't write 'return void' either.
That's because 'return [typename]' makes no sense. You're not writing 'return int' either. But returning a void is perfectly legal:
void foo();

void bar()
{
    return (void)23;  // ok
    return foo();     // ok
}

C++ addict
-
Currently working on: the 3D engine for Tomb Raider.

#9 poita

    Senior Member

  • Members
  • PipPipPipPip
  • 322 posts

Posted 27 May 2006 - 01:43 PM

.oisyn said:

The difference in C is that with (void), you're specifying that it has no parameters, while with () you're specifying that the parameters are unspecified (note that this is also different from (...), which means it can be called with any number and types of arguments). Of course the latter doesn't work in C++ with function overloads and all, plus the fact that it isn't very type-safe.

In fact it is ambiguous.
int main()

{

    bla(); // a function declaration or a function call expression?

}

So what's the difference between specifying no arguments and having unspecified arguments. (I'm using C++ btw)

Also, I don't see any ambiguity there. As far as I'm aware, you can't declare a function inside another function so it's definitely a call.


.oisyn said:

That's because 'return [typename]' makes no sense. You're not writing 'return int' either. But returning a void is perfectly legal:
void foo();


void bar()

{

    return (void)23;  // ok

    return foo();     // ok

}

What does casting to a void do? :blink:

#10 Nick

    Senior Member

  • Members
  • PipPipPipPip
  • 1227 posts
  • LocationOttawa, Ontario, Canada

Posted 27 May 2006 - 01:46 PM

.oisyn said:

The difference in C is that with (void), you're specifying that it has no parameters, while with () you're specifying that the parameters are unspecified...
Sorry? You make it sound like with () there are arguments but they are unspecified. Correct me if I'm wrong but there's diddly-squat difference between (void) and () beyond the syntax.

Quote

In fact it is ambiguous.
int main()

{

    bla(); // a function declaration or a function call expression?

}
I was utterly surprised writing void in front of bla actually compiled. :surrender

What's this useful for anyway?

#11 .oisyn

    DevMaster Staff

  • Moderators
  • 1842 posts

Posted 27 May 2006 - 02:54 PM

poita said:

So what's the difference between specifying no arguments and having unspecified arguments. (I'm using C++ btw)
It's only applicable to C, in C++ () and (void) have exactly the same meaning.
It's an old remnant in C, back in the days where people didn't care about safety ;)

// function that has no params
void foo(void);

// function that may have params, but I don't know what they are at this point
void bar();

// function that has no params
void baz()
{
}

int main()
{
    foo(); // ok, foo has no params
    foo(34); // error

    bar(); // ok, don't know what the params are so allow everything
    bar(1, 2, 3); // ok

    baz(); // ok, same as foo
    baz(34); // error
}

In a sourcefile, you are allowed to define bar with a parameter list:
void foo(void);
void bar();

void foo(int i) { } // error, different signature
void bar(int i) { } // ok, signature was unspecified earlier

Quote

Also, I don't see any ambiguity there. As far as I'm aware, you can't declare a function inside another function so it's definitely a call.
Then you are not aware ;). You can declare functions and variables just as well inside functions as you could outside functions. That's the whole reason why this doesn't do what you (probably) expect to:
class MyType
{
    MyType();
};

int main()
{
    MyType myVar(); // variable definition with default constructor initialization? Guess again!
}
myVar is a function returning a MyType

Quote

What does casting to a void do? :blink:
It voids the result of the expression ;)
C++ addict
-
Currently working on: the 3D engine for Tomb Raider.

#12 .oisyn

    DevMaster Staff

  • Moderators
  • 1842 posts

Posted 27 May 2006 - 02:58 PM

Nick said:

Sorry? You make it sound like with () there are arguments but they are unspecified. Correct me if I'm wrong but there's diddly-squat difference between (void) and () beyond the syntax.
See above, it only is in C. In C++ they are indeed exactly the same.

Quote

I was utterly surprised writing void in front of bla actually compiled. :surrender

What's this useful for anyway?
To declare functions inside other functions. The declaration only lives in the scope of the current block. This can be useful to avoid cluttering the global namespace in the current sourcefile:
namespace
{
    int someIdentifier = 0;
}

/* lot of code that uses someIdentifier
    ...
*/

/* then, you decide to include a library in your program
that has a function called 'someIdentifier' you need to use */
void someFunc()
{
    someIdentifier(23);  // error, someIdentifier is an int.
    void someIdentifier(int);
    someIdentifier(23);  // it's ok now
}
of course, if someIdentifier() is in a namespace you're screwed as you aren't allowed to declare namespaces inside functions as well (they need to fix that imo)
C++ addict
-
Currently working on: the 3D engine for Tomb Raider.

#13 poita

    Senior Member

  • Members
  • PipPipPipPip
  • 322 posts

Posted 27 May 2006 - 03:17 PM

.oisyn said:

It's only applicable to C, in C++ () and (void) have exactly the same meaning.
It's an old remnant in C, back in the days where people didn't care about safety ;)

Ah, I actually remember reading something about that back in the days of learning the language.

.oisyn said:

Then you are not aware ;). You can declare functions and variables just as well inside functions as you could outside functions. That's the whole reason why this doesn't do what you (probably) expect to:
class MyType

{

    MyType();

};


int main()

{

    MyType myVar(); // variable definition with default constructor initialization? Guess again!

}
myVar is a function returning a MyType

Wow, I've been missing out. Could come in handy.

.oisyn said:

It voids the result of the expression ;)

Is there any practical reason you'd want to do that?

#14 Nick

    Senior Member

  • Members
  • PipPipPipPip
  • 1227 posts
  • LocationOttawa, Ontario, Canada

Posted 27 May 2006 - 06:33 PM

Thanks for heads-up .oisyn!

I find it quite confusing though. I can't find a practicaly use for it that can't be done in a clean way otherwise. I believe that allowing to omit void for functions that don't return anything would be more useful and easier to understand. But if you have arguments why it's a good thing I'd love to hear them!

#15 bramz

    Valued Member

  • Members
  • PipPipPip
  • 189 posts

Posted 27 May 2006 - 07:26 PM

.oisyn said:

of course, if someIdentifier() is in a namespace you're screwed as you aren't allowed to declare namespaces inside functions as well (they need to fix that imo)

Then you would just write

void someFunc()
{
     someNamespace::someIdentifier(23);  // it's ok now
}

or maybe


void someFunc()
{
     using someNamespace::someIndentifier;
     someIdentifier(23);  // it's ok now
}

I'm not sure if the latter works though ...
hi, i'm a signature viruz, plz set me as your signature and help me spread :)
Bramz' warehouse | LiAR isn't a raytracer

#16 monjardin

    Senior Member

  • Members
  • PipPipPipPip
  • 1033 posts

Posted 27 May 2006 - 07:30 PM

We maintain C code that continues to cause issues because functions are declared with () and then defined with parameters. For example, some version of the system use float and other use doubles.

// foo.c

void foo(a, b)

float a;

float b;

{

   // do something with a and b

}


// bar.c

// we need foo, so declare it

void foo();


void bar()

{

    double a, b; // oops, I forgot the function takes floats

    a = 1.0;

    b = 2.0;

    foo(a, b); // this compiles and does NOT cast the params to floats

}

Be happy you have type safety that avoids this in C++. :wallbash:

@Nick: I think .oisyn aready answered your question. To support removal of void return types you would have to disallow declaration of functions within functions.
monjardin's JwN Meter (1,2,3,4,5,6):
|----|----|----|----|----|----|----|----|----|----|
*

#17 bramz

    Valued Member

  • Members
  • PipPipPip
  • 189 posts

Posted 27 May 2006 - 07:34 PM

Nick said:

Unfortunately C++ isn't consistent with that for functions. You can't omit the void in front of the function in the example above. Yet it would be completely unambiguous and safe as long as the compiler would enforce that you can't return any value from such function. Note by the way that we don't write 'return void' either.

The problem is that a certain popular compiler thinks the return type is int if you do so =)
hi, i'm a signature viruz, plz set me as your signature and help me spread :)
Bramz' warehouse | LiAR isn't a raytracer

#18 monjardin

    Senior Member

  • Members
  • PipPipPipPip
  • 1033 posts

Posted 27 May 2006 - 07:39 PM

@bramz: Neither of those work in the case described.
// someIdentifier.cpp
namespace someNamespace {
void someIdentifier(int) { ... }
}
// main.cpp
int main()
{
    someNamespace::someIdentifier(23); // this won't compile
    return 0;
}

monjardin's JwN Meter (1,2,3,4,5,6):
|----|----|----|----|----|----|----|----|----|----|
*

#19 Nick

    Senior Member

  • Members
  • PipPipPipPip
  • 1227 posts
  • LocationOttawa, Ontario, Canada

Posted 27 May 2006 - 07:42 PM

monjardin said:

I think .oisyn aready answered your question. To support removal of void return types you would have to disallow declaration of functions within functions.
Yes, I know, but my actual question was is it more useful to have declaration of functions within functions or have a more consistent syntax for functions that don't return anything? In other words: Is C++ flawed and should they fix this some time (if they could) or is there a good reason to keep declarations of functions within functions and we should just continue to write void in front of our declarations of functions that return nothing? :blink:

Does anyone know how C# handles this? I'm too lazy to check myself... :p

#20 monjardin

    Senior Member

  • Members
  • PipPipPipPip
  • 1033 posts

Posted 27 May 2006 - 07:50 PM

I really don't have an opinion either way. I don't recall the last time I declared a funciton inside a function. I think VC++ (6.0?) did assume and int return type at one point (as I believe bramz was alluding). All I have in front of me right now is 2005 express.

It says:

error C4430: missing type specifier - int assumed. Note: C++ does not support default-int

I don't know what C# does either and I don't have it on my laptop. :(
I'm too cheap to pay for Internet access at home when I can get it for free with a nice cup of coffee. :yes:
monjardin's JwN Meter (1,2,3,4,5,6):
|----|----|----|----|----|----|----|----|----|----|
*





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users