I've seen methods with the following signature:
void foo (void);
They take no argument, however I'm wondering whether doing this is useful or not. Is there a reason why you would want to do it?
This is a holdover from older versions of C, where foo() meant "a function with an unknown number of parameters" and foo(void) means "a function with zero parameters." In C++, foo() and foo(void) both mean "a function with zero parameters", but some people prefer the second form because it is more explicit.
The C++03 standard says (emphasis mine):
8.3.5.2
The parameter-declaration-clause determines the arguments that can be
specified, and their processing, when the function is called. [Note:
the parameter-declaration-clause is used to convert the arguments
specified on the function call; see 5.2.2. ] If the
parameter-declaration-clause is empty, the function takes no
arguments.
This means that if you are talking to the compiler it's just a matter of taste.
If you are writing code that will be read by others, then the C++ way of doing things is
void foo();
The other form remains valid only for reasons of compatibility with C, where there was a difference among the two signatures.
In C++ code there is no reason whatsoever to use void in this way. What's more it is very much not the idiomatic way to declare parameterless functions.
This is a legacy from the older versions of C for functions with no arguments.
Related
Basically, I am reading through this book right here and in Section 1.6: Some Differences between C and C++ it is stated:
Another subtle difference between C and C++ is that in a C++ program,
all functions must be prototyped.
I am sure that this is not true from all the C++ programs that I have written. Is this only true for some versions of C++? Is it also true for C?
It has been true of C++ since the beginning (although in C++ it's just called a "declaration", not a "prototype").
As C existed decades ago, it allowed you to call a function without declaring it. You could, however, declare a function if you wanted to--usually to tell the compiler that it had a return type different from what the compiler would deduce on its own. So, in C a function declaration looks something like this:
long f();
Note that empty parens there. That's what separates a function "declaration" from a function "prototype" (though a prototype is basically a superset of a declaration, so a prototype also declares the function in question). A prototype always has something inside the parens to indicate the number and type of parameters the function accepts, on this general order:
short g(int a, double b);
If it doesn't accept any parameters, you have to put in void to indicate that:
int h(void);
If you leave the parens empty, that (as noted above) means it's a function declaration instead of a prototype--and that means you're telling the compiler the function's return type, but you're not telling it anything about the number or type of parameters.
C++ (since before it was called C++, if I recall correctly) has only had one concept instead of the two in C. In C++ every function must be declared--and a declaration always includes the number of parameters, and the type of each. This is absolutely necessary to support (for one obvious example) function overloading, where the correct function to call is determined from the number and types of arguments you pass in the call.
A function definition in C++ also acts as a function declaration. Every function must be declared, but the declaration doesn't have to be separate from the definition.
In reasonably modern C, you normally get pretty much the same--that is, a "new" (i.e., not ancient) type function definition also acts as a prototype for that function. As C was originally defined, it included a syntax for a function definition that looked like this:
int f(a, b, c)
int a;
short b;
long c;
{
// function body here
}
This defines the function, but the compiler treats it only as a function declaration, not a prototype--that is, it tells the compiler the return type, but the number and types of parameters (even though they're specified) are not used by the compiler in the same way they would be with a function prototype. C++ has never used or supported this style of function definition though.
Can one in C++11 somehow in gcc mark a function (not a class method) as const telling that it is pure and does not use the global memory but only its arguments?
I've tried gcc's __attribute__((const)) and it is precisely what I want. But it does not produce any compile time error when the global memory is touched in the function.
Edit 1
Please be careful. I mean pure functions. Not constant functions. GCC's attribute is a little bit confusing. Pure functions only use their arguments.
Are you looking for constexpr? This tells the compiler that the function may be evaluated at compile time. A constexpr function must have literal return and parameter types and the body can only contain static asserts, typedefs, using declarations and directives and one return statement. A constexpr function may be called in a constant expression.
constexpr int add(int a, int b) { return a + b; }
int x[add(3, 6)];
Having looked at the meaning of __atribute__((const)), the answer is no, you cannot do this with standard C++. Using constexpr will achieve the same effect, but only on a much more limited set of functions. There is nothing stopping a compiler from making these optimizations on its own, however, as long as the compiled program behaves the same way (the as-if rule).
Because it has been mentioned a lot here, lets forget about Meta programming for now, which is pure functional anyway and off topic. However, a constexpr function foo can be called with non constexpr arguments and in this context foo is actually a pure function evaluated at runtime (I am ignoring global variables here). But you can write many pure functions that you cannot make constexpr, this includes any function throwing exceptions for example.
Second I assume the OP means marking pure as an assertion for the compiler to check. GCC's pure attribute is the opposite, a way for the coder to help the compiler.
While the answer to the OP's question is NO, it is very interesting to read about the history of attempts to introduce a pure keyword (or impure and let pure be the default).
The d-lang community quickly figured out that the meaning of "pure" is not clear. Logging should not make a function impure. Mutable variables that do not escape the function call should be allowed in pure functions. Equal return values having different addresses should not be considered impure. But D goes even further than that in stretching purity.
So the d-lang community introduced the term "weakly pure" and "strongly pure". But later disputes showed that weak and strong is not black and white and there are grey zones. see purity in D
Rust introduced the "pure" keyword early on; and they dropped it because of its complexity. see purity in Rust.
Among the great benefits of a "pure" keyword there is an ugly consequence though. A templated function can be pure or not depending on its type parameters. This can explode the number of template instantiations. Those instantiations may only need to exist temporarily in the compiler and not get into the executable but they can still explode compile times.
A syntax highlighting editor could be of some help here without modifying the language. Optimizing C++ compilers do actually reason about the pureness of a function, they just do not guarantee catching all cases.
I find it sad that this feature seems to have low priority. It makes reasoning about code so much easier. I would even argue that it would improve software design by the way it incentivizing programmers to think differently.
using just standard C++11:
namespace g{ int x; }
constexpr int foo()
{
//return g::x = 42; Nah, not constant
return 42; // OK
}
int main()
{}
here's another example:
constexpr int foo( int blah = 0 )
{
return blah + 42; // OK
}
int main( int argc, char** )
{
int bah[foo(2)]; // Very constant.
int const troll = foo( argc ); // Very non-constant.
}
The meaning of GCC's __attribute__( const ) is documented in the GNU compiler docs as …
Many functions do not examine any values except their arguments, and have no effects except the return value. Basically this is just slightly more strict class than the pure attribute below, since function is not allowed to read global memory.
One may take that to mean that the function result should only depend on the arguments, and that the function should have no side effects.
This allows a more general class of functions than C++11 constexpr, which makes the function inline, restricts arguments and function result to literal types, and restricts the "active" statements of the function body to a single return statement, where (C++11 §7.1.5/3)
— every constructor call and implicit conversion used in initializing the return value (6.6.3, 8.5) shall be one of those allowed in a constant expression (5.19)
As an example, it is difficult (I would think not impossible, but difficult) to make a constexpr sin function.
But the purity of the result matters only to two parties:
When known to be pure, the compiler can elide calls with known results.
This is mostly an optimization of macro-generated code. Replace macros with inline functions to avoid silly generation of identical sub-expressions.
When known to be pure, a programmer can remove a call entirely.
This is just a matter of proper documentation. :-)
So instead of looking for a way to express the purity of e.g. sin in the language, I suggest just avoid code generation via macros, and document pure functions as such.
And use constexpr for the functions where it's practically possible (unfortunately, as of Dec. 2012 the latest Visual C++ compiler doesn't yet support constexpr).
There is a previous SO question about the relationship between pure and constexpr. Mainly, every constexpr function is pure, but not vice versa.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Nonstatic member as a default argument of a nonstatic member function
Correct me if I am wrong, but the way I think default parameters work is this:
When the compiler sees the function call, it starts pushing the parameters onto the stack. When it runs out of parameters, it will start pushing the defaults onto the stack until all required parameters are filled (I know this is a simplification, since parameters are actually pushed from right to left, so it will start with the defaults, but the idea is the same).
If this is true, why can't member variables be used as defaults? It seems to me that since the compiler is pushing them as usual at the call site, it should be able to resolve them just fine!
EDIT Since it seems by the answers my question was misunderstood, let me clarify. I know this is the case, and I know what is and isn't allowed by the language. My question is why did the language designers choose to not allow this, since it seems to naturally work.
The essence of what you are asking can be distilled into this simple example
void foo(int a, int b = a);
This is not allowed in C++. C++ does not allow default arguments to depend on other parameters.
Using class members as default arguments is just a particular case of the above, since class members are accessed through this pointer and this pointer is just another hidden parameter of each non-static member function.
So, the question is really why
void foo(int a, int b = a);
is not allowed.
One obvious potential reason to disallow this is that it would impose additional requirements on the order of argument evaluation. As you know, in C++ the order of function argument evaluation is unspecified - the compiler can evaluate arguments in any order. However, in order to support the above default argument functionality the compiler would have to make sure that a is evaluated before b. This feels like an excessive requirement, which restricts the typical freedom of evaluation order that we are used to seeing in C++.
Note that this
int a;
void foo(int b = a);
is allowed in C++. And, obviously, it does not exhibit the aforementioned order of evaluation issue.
I believe this are the most fitting paragraphs from the standard, especially §9:
8.3.6 Default arguments [dcl.fct.default]
§7 Local variables shall not be used in a default argument
§9 [...] Similarly, a non-static member shall not be used in a default argument, even if it is not evaluated, unless it appears as the id-expression of a class member access expression (5.2.5) or unless it is used to form a pointer to member (5.3.1).
This post lists all ways a default param can be set - Must default function parameters be constant in C++?
It's not difficult to workaround your need.
class A
{
int a;
public:
void f(int i);
void f()
{
f(a);
}
};
gives you what you want.
Summarizing Nawaz excellent answer in the linked question: The call to void Foo::Bar(int a = this->member) really means void Foo__Bar(Foo* this, int a = this->member). Obviously the second argument cannot be evaluated before the first, which violates a C++ axiom that compilers can evaluate arguments in whatever order they like.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
C++ Why put void in params?
What's the difference between these two declarations and which is used more commonly?
void function1();
and
void function2( void );
There is no difference in C++, where it is well defined that it represents 0 parameters.
However it does make one in C. A function with (void) means with no parameter, whereas () means with any number of parameters.
From http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8a.doc%2Flanguage%2Fref%2Fparam_decl.htm
An empty argument list in a function definition indicates that a function
that takes no arguments. An empty argument list in a function declaration
indicates that a function may take any number or type of arguments. Thus,
int f()
{
...
}
indicates that function f takes no arguments. However,
int f();
simply indicates that the number and type of parameters is not known.
To explicitly indicate that a function does not take any arguments, you should
define the function with the keyword void.
There is no difference in C++.
The second declaration just explicitly says that function takes no parameter.
Second is more commonly used in C, First is the one that is more common in C++.
There is a difference in case of C because:
With (void), you're specifying that the function has no parameters, while with () you are specifying that the parameters are unspecified(unknown number of arguments).
However, if it was not a function declaration but a function definition, then even in C it is same as (void).
There is no difference. I'd say the first one is more common, clear and concise.
In C++, there is no difference, and the second form is only retained for C compatibility. The first form is preferred in C++.
In C, they mean different things.
The first form specifies a function which takes an unknown number of arguments, and the second is a function taking zero arguments.
Some very old (non-standard) C compiler might complain about the first one, so the second one should be more portable.
Apart from that, there is no difference.
The first one is used more commonly in user code, quite simply because it's shorter.
actually there is no difference .if you have not any parameters to pass to the method user void or empty parentheses .notice that it just fro passed parameters.if your method has not any returned value you have to use void keyword.the first one is more common in C#
So one of my previous exams had this question, and till now I've been reading that you don't need a declaration in any of the languages?
Which is right? Will C++ give an error if there's no declaration, or will it run?
In a discussion that involves both C and C++ "function declaration" is a rather vague term. These languages are significantly different in this regard.
In C++ language there's only one kind of function declaration: declaration with all parameter types and return type. Such declarations are necessary because C++ language supports function overloading. In order to choose which function to call the compiler needs to know everything about the function and needs to know which overloaded versions of the function are available. If you "forget" to declare some overloaded version, it will not be considered by overload resolution. That is at least one of the reasons function declarations are necessary in C++.
In C language there are two kinds of function declarations: non-prototype declarations and prototype declarations (or simply prototypes). A prototype in C is pretty similar to C++ declaration - it includes all parameter types. Prototypes have always been required in standard C for variadic functions (functions with ... parameters). For non-variadic functions prototype declarations are not required even today. But starting from C99 at least non-prototype declarations are required for all other functions. In older C89/90 version of the language function declarations for non-variadic functions were not required.
So, that should basically answer your question. In C++ function declarations are required because language features rely on them critically. In modern C function declarations are also required just to make the code safer. In older versions of C function declarations were not required mostly simply because the language was defined to work without them.
Function declarations in C are not mandatory for legacy / backwards compatability reasons - if they were made mandatory then some old / legacy code somewhere would stop compiling.
I'd guess that they are mandatory in C++ becasuse C++ isn't a strict superset of C and so can make the sensible choice of making them mandatory.
You should always declare them however - see this question Must declare function prototype in C?
FYI in C99 function declarations are now mandatory.
Function declarations are mandatory in C. Prototypes, however, are optional, except in the cases of variadic functions and functions whose argument types would be altered by default promotions.
I can't answer for C.
In C++, for functions:
void foo(); is a declaration.
void foo() { .. } is a definition and a declaration.
You need at least one declaration in scope before you call foo().
Much the same is true for data variables.