Why is no argument in a function prototype preferred? - c++

I have a question about coding style in C++.
I prefer to use void explicitly in function prototypes.
However, during reading an article about void type in Wikipedia, I have seen that giving no argument in a function prototype is preferred.
Why is no argument in the prototype preferred?
I am so curious if there is a specific reason.

C++ had function prototypes before C did, and C++ has 'always' required prototypes in effect. Therefore, there was no problem or ambiguity about empty brackets (parentheses) meaning no arguments.
By contrast, C did not acquire function prototypes until long after C++ had them, and it had a legacy base to deal with. Until function prototypes were introduced, C functions with non-integer return types had to be declared as:
double sin();
char *malloc(); /* There wasn't void * -- or C++ style // comments */
struct whatnot *new_whatnot();
The C standardization committee could not afford to break all the existing C code; the standard would have failed. So, the C standardizers adopted sometype function(void) to indicate explicitly 'no arguments'. To this day, sometype function() means 'a function returning a sometype value taking an undefined (but not variable) number of arguments of undefined type'.
Because C++ had the empty brackets (empty parentheses) notation, there was no need for the (void) notation, but it was added to C++ to match the C standard and make it easier to migrate code between standard C and C++.
Code written natively for C++ should use the native, empty brackets notation.
Code written natively for C must use the explicit (void) notation because the empty parentheses means something quite different (and relatively undesirable).
Code written to be migratable between C and C++ might use the explicit (void) notation to ensure that both compilers see the same specification.

What is prefered and what is a good practice are quite different. I believe that is just a choice of the programmer.

Related

C vs C++ function questions

I am learning C, and after starting out learning C++ as my first compiled language, I decided to "go back to basics" and learn C.
There are two questions that I have concerning the ways each language deals with functions.
Firstly, why does C "not care" about the scope that functions are defined in, whereas C++ does?
For example,
int main()
{
donothing();
return 0;
}
void donothing() { }
the above will not compile in a C++ compiler, whereas it will compile in a C compiler. Why is this? Isn't C++ mostly just an extension on C, and should be mostly "backward compatible"?
Secondly, the book that I found (Link to pdf) does not seem to state a return type for the main function. I check around and found other books and websites and these also commonly do not specify return types for the main function. If I try to compile a program that does not specify a return type for main, it compiles fine (although with some warnings) in a C compiler, but it doesn't compile in a C++ compiler. Again, why is that? Is it better style to always specify the return type as an integer rather than leaving it out?
Thanks for any help, and just as a side note, if anyone can suggest a better book that I should buy that would be great!
Firstly, why does C "not care" about the scope that functions are defined in, whereas C++ does?
Actually, C does care. It’s just that C89 allows implicitly declared functions and infers its return type as int and its parameters from usage. C99 no longer allows this.
So in your example it’s as if you had declared a prototype as
int dosomething();
The same goes for implicit return types: missing return types are inferred as int in C89 but not C99. Compiling your code with gcc -std=c99 -pedantic-errors yields something similar to the following:
main.c: In function 'main':
main.c:2:5: error: implicit declaration of function 'donothing' [-Wimplicit-function-declaration]
main.c: At top level:
main.c:5:6: error: conflicting types for 'donothing'
main.c:2:5: note: previous implicit declaration of 'donothing' was her
For the record, here’s the code I’ve used:
int main() {
donothing();
return 0;
}
void donothing() { }
It's because C++ supports optional parameters. When C++ sees donothing(); it can't tell if donothing is:
void donothing(void);
or
void donothing(int j = 0);
It has to pass different parameters in these two cases. It's also because C++ is more strongly typed than C.
int main() {
donothing();
return 0;
}
void donothing() { }
Nice minimum working example.
With gcc 4.2.1, the above code gets a warning regarding the conflicting types for void donothing() with default compiler settings. That's what the C89 standard says to do with this kind of problem. With clang, the above code fails on void donothing(). The C99 standard is a bit stricter.
It's a good idea to compile your C++ code with warnings enabled and set to a high threshold. This becomes even more important in C. Compile with warnings enabled and treat implicit function declarations as an error.
Another difference between C and C++: In C++ there is no difference between the declarations void donothing(void); and void donothing(); There is a huge difference between these two in C. The first is a function that takes no parameters. The latter is a function with an unspecified calling sequence.
Never use donothing() to specify a function that takes no arguments. The compiler has no choice but to accept donothing(1,2,3) with this form. It knows to reject donothing(1,2,3) when the function is declared as void donothing(void).
he above will not compile in a C++ compiler, whereas it will compile in a C compiler. Why is this?
Because C++ requires a declaration (or definition) of the function to be in scope at the point of the call.
Isn't C++ mostly just an extension on C
Not exactly. It was originally based on a set of C extensions, and it refers to the C standard (with a few modifications) for the definitions of the contents of standard headers from C. The C++ "language itself" is similar to C but is not an extension of it.
and should be mostly "backward compatible"?
Emphasis on "mostly". Most C features are available in C++, and a lot of the ones removed were to make C++ a more strictly typed language than C. But there's no particular expectation that C code will compile as C++. Even when it does, it doesn't always have the same meaning.
I check around and found other books and websites and these also commonly do not specify return types for the main function
The C and C++ standards have always said that main returns int.
In C89, if you omit the return type of a function it is assumed to be int. C++ and C99 both lack this implicit int return type, but a lot of C tutorial books and tutorials (and compilers and code) still use the C89 standard.
C has some allowances for implementations to accept other return types, but not for portable programs to demand them. Both languages have a concept of a "freestanding implementation", which can define program entry and exit any way it likes -- again, because this is specific to an implementation it's not suitable for general teaching of C.
IMO, even if you're going to use a C89 compiler it's worth writing your code to also be valid C99 (especially if you have a C99 compiler available to check it). The features removed in C99 were considered harmful in some way. It's not worth even trying to write code that's both C and C++, except in header files intended for inter-operation between the languages.
I decided to "go back to basics" and learn C.
You shouldn't think of C as a prerequisite or "basic form" of C++, because it isn't. It is a simpler language, though, with fewer features for higher-level programming. This is often cited as an advantage of C by users of C. And an advantage of C++ by users of C++. Sometimes those users are the same people using the languages for different purposes.
Typical coding style in C is different from typical coding style in C++, and so you might well learn certain basics more readily in C than in C++. It is possible to learn low-level programming using C++, and the code you write when you do so may or may not end up looking a lot like C code.
So, what you learn while learning C may or may not inform the way you write C++. If it does, that may or may not be for the better.
C++ has changed these rules on purpose, to make C++ a more typesafe language.
C.1.4 Clause 5: expressions [diff.expr]
5.2.2
Change: Implicit declaration of functions is not allowed
Rationale: The type-safe nature of C++.
Effect on original feature: Deletion of semantically well-defined feature. Note: the original feature was
labeled as “obsolescent” in ISO C.
Difficulty of converting: Syntactic transformation. Facilities for producing explicit function declarations
are fairly widespread commercially.
How widely used: Common.
You can find other similar changes in appendix C of this Draft C++ standard
Isn't C++ mostly just an extension on C
No. If you think of C++ as "C with Classes", you're doing it very, very wrong. Whilst strictly, most valid C is valid C++, there's virtually no good C that's good C++. The reality is that good C++ code is vastly different to what you'd see as good C code.
Firstly, why does C "not care" about the scope that functions are
defined in, whereas C++ does?
Essentially, because not enforcing the same rules as C++ makes doing this in C hideously unsafe and in fact, nobody sane should ever do that. C99 tightened this up, along with implicit-int and other defects in the C language.

Using void in functions without parameter?

In C++ using void in a function with no parameter, for example:
class WinMessage
{
public:
BOOL Translate(void);
};
is redundant, you might as well just write Translate();.
I, myself generally include it since it's a bit helpful when code-completion supporting IDEs display a void, since it ensures me that the function takes definitely no parameter.
My question is, Is adding void to parameter-less functions a good practice? Should it be encouraged in modern code?
In C++
void f(void);
is identical to:
void f();
The fact that the first style can still be legally written can be attributed to C.
n3290 § C.1.7 (C++ and ISO C compatibility) states:
Change: In C++, a function declared with an empty parameter list takes
no arguments.
In C, an empty parameter list means that the number and
type of the function arguments are unknown.
Example:
int f(); // means int f(void) in C++
// int f( unknown ) in C
In C, it makes sense to avoid that undesirable "unknown" meaning. In C++, it's superfluous.
Short answer: in C++ it's a hangover from too much C programming. That puts it in the "don't do it unless you really have to" bracket for C++ in my view.
I see absolutely no reason for this. IDEs will just complete the function call with an empty argument list, and 4 characters less.
Personally I believe this is making the already verbose C++ even more verbose. There's no version of the language I'm aware of that requires the use of void here.
I think it will only help in backward compatibility with older C code, otherwise it is redundant.
I feel like no. Reasons:
A lot more code out there has the BOOL Translate() form, so others reading your code will be more comfortable and productive with it.
Having less on the screen (especially something redundant like this) means less thinking for somebody reading your code.
Sometimes people, who didn't program in C in 1988, ask "What does foo(void) mean?"
Just as a side note. Another reason for not including the void is that software, like starUML, that can read code and generate class diagrams, read the void as a parameter. Even though this may be a flaw in the UML generating software, it is still annoying to have to go back and remove the "void"s if you want to have clean diagrams

How does this function definition work?

I generated a hash function with gperf couple of days ago. What I saw for the hash function was alien to me. It was something like this (I don't remember the exact syntax) :
unsigned int
hash(str, size)
register char* str;
register unsigned int size;
{
//Definition
}
Now, when I tried to compile with a C++ compiler (g++) it threw errors at me for not having str and size declared. But this compiled on the C compiler (gcc). So, questions:
I thought C++ was a superset of C. If its so, this should compile with a C++ compiler as well right?
How does the C compiler understand the definition? str and size are undeclared when they first appear.
What is the purpose of declaring str and size after function signature but before function body rather than following the normal approach of doing it in either of the two places?
How do I get this function to compile on g++ so I can use it in my C++ code? Or should I try generating C++ code from gperf? Is that possible?
1. C++ is not a superset, although this is not standard C either.
2/3. This is a K&R function declaration. See What are the major differences between ANSI C and K&R C?
.
4. gperf does in fact have an option, -L, to specify the language. You can just use -L C++ to use C++.
The Old C syntax for the declaration of a function's formal arguments is still supported by some compilers.
For example
int func (x)
int x
{
}
is old style (K&R style) syntax for defining a function.
I thought C++ was a superset of C. If its so, this should compile with a C++ compiler as well right?
Nopes! C++ is not a superset of C. This style(syntax) of function declaration/definition was once a part of C but has never been a part of C++. So it shouldn't compile with a C++ compiler.
This appears to be "old-school" C code. Declaring the types of the parameters outside of the parentheses but before the open curl-brace of the code block is a relic of the early days of C programming (I'm not sure why but I guess it has something to do with variable management on the stack and/or compiler design).
To answer your questions:
Calling C++ a "superset" of C is somewhat a misnomer. While they share basic syntax features, and you can even make all sorts of C library calls from C++, they have striking differences with respect to type safety, warnings vs. errors (C is more permissible), and compiler/preprocessor options.
Most contemporary C compilers understand legacy code (such as this appears to be). The C compiler holds the function parameter names sort of like "placeholders" until their type can be declared immediately following the function header name.
No real "purpose" other than again, this appears to be ancient code, and the style back in the day was like this. The "normal" approach is IMO the better, more intuitive way.
My suggestion:
unsigned int hash(register char *str, register unsigned int size)
{
// Definition
}
A word of advice: Consider abandoning the register keyword - this was used in old C programs as a way of specifying that the variable would be stored in a memory register (for speed/efficiency), but nowadays compilers are better at optimizing away this need. I believe that modern compilers ignore it. Also, you cannot use the & (address of) operator in C/C++ on a register variable.

Using Fortran to call C++ Functions

I'm trying to get some FORTRAN code to call a couple c++ functions that I wrote (c_tabs_ being one of them). Linking and everything works just fine, as long as I'm calling functions that don't belong to a class.
My problem is that the functions I want the FORTRAN code to call belong to a class. I looked at the symbol table using nm and the function name is something ugly like this:
00000000 T _ZN9Interface7c_tabs_Ev
FORTRAN won't allow me to call a function by that name, because of the underscore at the beginning, so I'm at a loss.
The symbol for c_tabs when it's not in a class is quite simple, and FORTRAN has no problems with it:
00000030 T c_tabs_
Any suggestions? Thanks in advance.
The name has been mangled, which is what the C++ compiler does to functions to allow things like function overloading and type-safe linkage. Frankly, you are extremely unlikely to be able to call member functions from FORTRAN (because FORTRAN cannot create C++ class instances, among other reasons) - you should express your interface in terms of a C API, which will be callable from just about anywhere.
You will need to create a c-style interface and "extern" it. C++ mangles method names (and overloaded functions) for linking. It's notoriously difficult to link C++ with anything except C++. There are "ways" but I'd highly suggest that you simply export a C interface and use the standard facilities available in Fortran.
If you make the C++ routine have a C-style interface (as described already), then you can use the ISO C Binding feature of Fortran 2003 to call it. With the ISO C Binding, you can specify the name of the routine and (within limits) the C-types and calling conventions (reference, by value) of the arguments and function return. This method works well and has the advantage of being a standard, and therefore compiler and platform dependent, unlike the old methods of calling C from Fortran. The ISO C Binding is supported by many Fortran 95 compilers, such as gfortran >= 4.3.
You have to create extern "C" wrappers to handle all the details of FORTRAN calling C++, name mangling being the most obvious.
class foo {
public:
int a_method (int x);
}
extern "C" int foo_a (foo * pfoo, int * px) {
if (NULL == pfoo)
return 0;
else
return pfoo->a_method (*px);
}
Notice that FORTRAN compilers pass all arguments by reference, never by value. (Although I'm told this is not strictly speaking part of the FORTRAN standard.)

Which is preferred: foo(void) or foo() in C++

I have seen two styles of defining conversion operator overload in C++,
operator int* (void) const
operator int*() const
Question 1. I think the two styles (whether add void or not) have the same function, correct?
Question 2. Any preference which is better?
This doesn't just apply to conversion operators but to all functions in C++ that take no parameters. Personally, I prefer to omit void for consistency.
The practice originates from C. Originally, when C did not have prototypes, an empty pair of braces was used in function declarations and did not provide any information about the parameters that the function expected.
When prototypes were added, empty braces were retained for function declarations to mean 'unspecified parameters' for flexibility and backwards compatibility. To provide an explicit prototype meaning 'takes no parameters', the syntax (void) was added.
In C++ all function declarations have to have prototypes, so () and (void) have the same meaning.
Quoting from ISO C++ FAQ, Should I use f(void) or f()?
C programmers often use f(void) when declaring a function that takes no parameters, however in C++ that is considered bad style. In fact, the f(void) style has been called an "abomination" by Bjarne Stroustrup, the creator of C++, Dennis Ritchie, the co-creator of C, and Doug McIlroy, head of the research department where Unix was born.
If you're writing C++ code, you should use f(). The f(void) style is legal in C++, but only to make it easier to compile C code.
Appeal to authority FTW :)
In C++ foo() and foo(void) are the same - "no arguments". In the C99 standard, the former means "undefined number of arguments", while the latter means "no arguments".
However, if you rely on the foo() behavior in C, you should be shot.
So this means that you can use either. Now personally, I like foo() better than foo(void), since I hate visual clutter, but that's just preference. I'm a Python guy :)
I believe in 'older' C (don't know what version) foo() meant 'any parameters' whereas foo(void) meant no parameters. foo() 'any parameters' version has been deprecated I believe in c99.
Quick googling finds this wikipedia article mentioning similar fact.
C++ will accept foo(void) but it means the same as foo() which means 'no parameters'.
So in C++ the preferred way is to use foo().
omit the void. In old style C all functions were assumed to be int name(...). Specifying void meant it was not a variable length parameter. That default was removed and all functions had to be specified (thankfully. It was the wild west when anything could be anything). In C++ you dont need to write (void) ever. Omit it. Just as the C++ libs do.