Using void in functions without parameter? - c++

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

Related

Why is no argument in a function prototype preferred?

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.

Why do compilers only look backward for type and function declarations?

This is purely to satisfy my own curiosity, but why are functions and types only resolved against those defined earlier in the code, rather than anywhere within the same scope?
Sometimes it shows up when functions need to call each other:
void foo(int depth) { bar(depth + 2); }
void bar(int depth) { if (depth > 0) foo(depth - 3); }
Where you either need to move bar to before foo, or declare bar beforehand:
void bar(int);
void foo(int depth) { bar(depth + 2); }
void bar(int depth) { if (depth > 0) foo(depth - 3); }
In more complex examples you may need to review the #include tree and #ifndef guards to figure out why your code does not recognize a function or type defined in some other file, and that's if you already know you're supposed to check for that.
And then of course there's this classic:
typedef struct {
Node *next;
} Node;
Where you need to know that this is possible:
typedef struct Node {
struct Node *next;
} Node;
...but apparently many people don't so they just use 'void *' or 'struct Node' everywhere.
So, is there a reason why these compilers don't resolve forward too? I can understand the preprocessor only checking backward since things can be #undefined, but once a type or function is declared it's there for good and can't be overloaded by a later definition.
Is it for historical reasons, with the limited technology that was available when they were first developed? Or is there some logical ambiguity I'm missing?
The answer to your question is simply that "It would make it much harder to write a compiler if it didn't" - the language specification says that it has to be this way, but the reason for this wording in the language specification is that "it makes it easier to write a compiler that way". To some degree, it's probably also that in the old days, compilers would generate code "as they went along", and not read all the code in a translation unit (source file) first, then process it.
Bear in mind that C and C++ compilers are still being used on machines that don't have huge amounts of memory and very fast processors. So, if you try to compile LARGE amounts of code on a small capacity machine, then the "we don't want to read ALL of the source first, then prase it" approach makes more sense than on a 16GB, quad-core desktop machine. I expect you could load the entire source code for a fairly large project into memory all at once (for example, all of the files in LLVM + Clang is around 450MB, so could easily fit in memory on a modern desktop/laptop).
Edit: It should be noted that "interpreted languages", such as PHP, JavaScript and Basic, typically don't have this requirement, but other compiled languages typically do - for example Pascal has a special keyword forward to tell the compiler that this function exists, but I'm telling you what it contains later.
Both Pascal and C (and C++ because it's based on C in this aspect) allow for pointers to structures that aren't complete yet. Just this simple "you don't have all the information yet" means that the compiler has to build up the type information, and then "go back and fix it up" [obviously only as required]. But it allows us to do:
struct X
{
struct X* next;
...
};
or in C++:
struct X
{
X* next;
...
};
Edit2: This blog by Jan Hubicka, a GCC developer, explains some of the problems with "dealing with all the code at once". Of course, most of us aren't compiling Firefox and similar size projects, but large projects, when you have to deal with ALL of the code at once, do cause problems with "not enough memory available" even with modern machines if the developers don't "put the compiler on a diet from time to time".
http://hubicka.blogspot.co.uk/2014/04/linktime-optimization-in-gcc-1-brief.html
The reason is that all necessary information of an entity being present when needed allows the compiler to translate a source file in a single pass. Cf. http://blogs.msdn.com/b/ericlippert/archive/2010/02/04/how-many-passes.aspx, for a comparison with C# (which doesn't require previous declarations; but then everything is in a class anyway).
C shares this feature with Pascal and a few other languages. Writing such a compiler is easier and, as others pointed out, tends to use less memory (but potentially increases compilation time, paradoxically, because the declarations in headers are being parsed/compiled over and over again for each translation unit).
Because any kind of logical deduction requires some kind of "logical order of things".
You deliberately ignore the order of things, to express your point here. Ok, nice, but this is very ignorant.
In C and C++ you have an order that kind of tries to workaround some typical problems: declaration and definition. In C/C++ you can refer to things that are at least declared, even if they were not yet defined.
But, this separation or "declared" and "defined" is just a relaxation of logical order, which --- in the end --- is just a simplification of things.
Imagine a pure plain language sequence of expressions to describe your program (in contrast to any programming language, which tries to express the same, but even tries to "compile" in into some practical computer program): A is B, but B depends on C, but B is like C only if A is to B what D may be to A what C may be to A what D is to C.
WTF???
If you can deduce a real world solution to a dedicated real world problem in a kind that does not depend on any logical order, then you will know your answer, and you may become very rich, just by knowing it.

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.

Could C++ or C99 theoretically be compiled to equally-portable C90?

This is a big question, so let me get a few things out of the way:
Let's ignore the fact that some C++ features cannot be implemented in C (for example, supporting pre-main initialization for any global static object that is linked in).
This is a thought experiment about what is theoretically possible. Please do not write to say how hard this would be (I know), or that I should do X instead. It's not a practical question, it's a fun theoretical one. :)
The question is: is it theoretically possible to compile C++ or C99 to C89 that is as portable as the original source code?
Cfront and Comeau C/C++ do compile C++ to C already. But for Comeau the C they produce is not portable, according to Comeau's sales staff. I have not used the Comeau compiler myself, but I speculate that the reasons for this are:
Macros such as INT_MAX, offsetof(), etc. have already been expanded, and their expansion is platform-specific.
Conditional compilation such as #ifdef has already been resolved.
My question is whether these problems could possibly be surmounted in a robust way. In other words, could a perfect C++ to C compiler be written (modulo the unsupportable C++ features)?
The trick is that you have to expand macros enough to do a robust parse, but then fold them back into their unexpanded forms (so they are again portable and platform-independent). But are there cases where this is fundamentally impossible?
It would be very difficult for anyone to categorically say "yes, this is possible" but I'm very interested in seeing any specific counterexamples: code snippets that could not be compiled in this way for some deep reason. I'm interested in both C++ and C99 counterexamples.
I'll start out with a rough example just to give a flavor of what I think a counterexample might look like.
#ifdef __SSE__
#define OP <
#else
#define OP >
#endif
class Foo {
public:
bool operator <(const Foo& other) { return true; }
bool operator >(const Foo& other) { return false; }
};
bool f() { return Foo() OP Foo(); }
This is tricky because the value of OP and therefore the method call that is generated here is platform-specific. But it seems like it would be possible for the compiler to recognize that the statement's parse tree is dependent on a macro's value, and expand the possibilities of the macro into something like:
bool f() {
#if __SSE__
return Foo_operator_lessthan(...);
#else
return Foo_operator_greaterthan(...);
#endif
}
It is not only theoretically possible, but also practically trivial - use LLVM with a cbe target.
Theoretically all Turing-complete languages are equivalent.
You can compile C++ to an object code, and then decompile it to plain C or use an interpreter written in plain C.
In theory of course anything could be compiled to C first, but it is not practical to do so, specifically for C++.
For Foo operator< in your example it could be converted to:
bool isLess(const struct Foo * left, const struct Foo * right );
as a function signature. (If C90 doesn't allow bool then return int or char, and similarly old C versions that don't allow const, just don't use it).
Virtual functions are more tricky, you need function pointers.
struct A
{
virtual int method( const std::string & str );
};
struct A
{
int (*method)( struct A*, const struct string *);
};
a.method( "Hello" );
a.method( &a, create_String( "hello" ) );
// and take care of the pointer returned by create_String
There are a number of subtle differences. For example, consider the line:
int i = UINT_MAX;
IIRC, in C++ this assigns an implementation-defined value. In C99 and C89, it assigns an implementation-defined value, or raises an implementation-defined signal. So if you see this line in C++, you can't just pass it through to a C89 compiler unmodified unless you make the non-portable assumption that it won't raise a signal.
Btw, if I've remembered wrong, think of your own example of differences in the standards relating to relatively simple expressions...
So, as "grep" says, you can do it because C89 is a rich enough language to express general computation. On the same grounds, you could write a C++ compiler that emits Perl source.
By the sound of your question, though, you're imagining that the compiler would make a set of defined modifications to the original code to make it compile as C89. In fact, even for simple expressions in C++ or C99, the C89 emitted might not look very much like the original source at all.
Also, I've ignored that there may be some parts of the standard libraries you just can't implement, because C89 doesn't offer the capabilities, so you'd end up with a "compiler" but not a complete implementation. I'm not sure. And as dribeas points out, low-level functions like VLAs present problems - basically you can't portably use the C89 "stack" as your C99 "stack". Instead you'd have to dynamically allocate memory from C89 to use for automatic variables required in the C99 source.
One big problem is exceptions. It might be possible to emulate them using setjmp, longjmp etc., but this would always be extremely inefficient compared to a real device-aware unwind engine.
http://www.comeaucomputing.com
There's no better proof of feasibility than a working example. Comeau is one of the most conforming c++03 compiler, and has support for many features of the upcoming standard, but it does not really generate binary code. It just translates your c++ code into c code that can be compiled with different C backends.
As for portability, I would assume it is not possible. There are some features that cannot be implemented without compiler specific extensions. The first example that comes to mind is C99 dynamic arrays: int n; int array[n]; that cannot be implemented in pure C89 (AFAIK) but can be implemented on top of extensions like alloca.

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.