Sorry for the vague title. I don't know how to phrase this issue.
I am practicing the use of pointers in C++ by rewriting a mergesort program by passing reference, but have run into an issue. To create a scratch array in a non-recursive method, I made the wrapper function...
void mergesort(int *low, int *high){
int *barr = new int[high-low+1];
mergesort(*low, *high, *barr);
}
...which in the end calls the function...
void mergesort(int *low, int *high, int *barr){
int *mid;
if(high - low < 2)
return;
int interval = high - low;
*mid = interval/2;
mergesort(low, mid, barr);
mergesort(mid, high, barr);
merge(low, high, barr);
}
...but I am getting the error 'mergesort': function does not take 3 arguments. Well, no duh, Visual Studio. Why does it not see the latter function instead of calling itself?
I tried fixing the issue originally by throwing away clever coding conventions and just renaming the wrapper function mergesortwrap(int *low, int *high) and changing the call in the main, but then I get the error 'mergesort': identifier not found. I am a Java kiddie. I don't understand this at all. Many thanks to anyone who can help.
Unlike in some other languages, free function declarations are not "hoisted" in C++. They are only available where they have been previously declared (or when you're inside a member function definition and are trying to name another member function).
That is why headers, which are typically included at the top of source files, conventionally have declarations:
void mergesort(int *low, int *high, int *barr);
void mergesort(int *low, int *high);
Then you can define them wherever you want but everywhere will be aware that these functions exist… including in the functions themselves.
A quick fix in your particular case is to swap the definitions around, since the overload taking three arguments doesn't need to know about the overload taking two arguments.
You need to write a forward declaration of the 3-legged overload before using it:
void mergesort(int *low, int *high, int *barr);
void mergesort(int *low, int *high){
int *barr = new int[high-low+1];
mergesort(*low, *high, *barr); // OK now
}
Alternatively, you can also define the 3-legged overload before the 2-legged one, but if the former would also call the latter, then you'd still have to forward declare it.
The only exception is when both functions are members of a class, because the whole class definition is being parsed before the member definitions.
Related
I will admit I have not kept up with the latest C/C++ releases but I was wondering why having a function prototype in a function is valid code? Is it related to lambda usage?
Here is sample code - this will compile/run on Visual Studio 2019 and g++ 5.4.0
int main()
{
int func(bool test);
return 0;
}
A code block may contain any number of declarations. And because a function prototype is a declaration, it may appear in a block.
Granted, it doesn't make much sense to do so logistically as opposed to declaring a function at file scope, but it's syntactically correct.
In that example the declaration is pointless. But in a more complex example it's not:
int main() {
int func(bool test);
func(true);
return 0;
}
That code is equivalent to the more usual formulation:
int func(bool test);
int main() {
int func(bool test);
func(true);
return 0;
}
except that the first one introduces the name func only inside the scope of main; the second one introduces the name into the global scope.
I occasionally use the first form when I don't want to scroll through the source file to figure out where to put the declaration; putting it in the function where it's going to be used is a quick-and-dirty solution. And if it's temporary code (adding debugging output, for example), it makes it easier to remove it all afterwards. But, in general, having declarations at global scope is simpler to deal with. After all, you might want to call that same function from somewhere else, too, and having the global declaration means you don't have to repeat it.
I was taught that functions need declarations to be called. To illustrate, the following example would give me an error as there is no declaration for the function sum:
#include <iostream>
int main() {
std::cout << "The result is " << sum(1, 2);
return 0;
}
int sum(int x, int y) {
return x + y;
}
// main.cpp:4:36: error: use of undeclared identifier 'sum'
// std::cout << "The result is " << sum(1, 2);
// ^
// 1 error generated.
To fix this, I'd add the declaration:
#include <iostream>
int sum(int x, int y); // declaration
int main() {
std::cout << "The result is " << sum(1, 2);
return 0;
}
int sum(int x, int y) {
return x + y;
}
Why the main function doesn't need the declaration, as other functions like sum need?
A definition of a function is also a declaration of a function.
The purpose of a declaring a function is to make it known to the compiler. Declaring a function without defining it allows a function to be used in places where it is inconvenient to define it. For example:
If a function is used in a source file (A) other than the one it is defined in (B), we need to declare it in A (usually via a header that A includes, such as B.h).
If two or more functions may call each other, then we cannot define all those functions before the others—one of them has to be first. So declarations can be provided first, with definitions coming afterward.
Many people prefer to put “higher level” routines earlier in a source file and subroutines later. Since those “higher level” routines call various subroutines, the subroutines must be declared earlier.
In C++, a user program never calls main, so it never needs a declaration before the definition. (Note that you could provide one if you wished. There is nothing special about a declaration of main in this regard.) In C, a program can call main. In that case, it does require that a declaration be visible before the call.
Note that main does need to be known to the code that calls it. This is special code in what is typically called the C++ runtime startup code. The linker includes that code for you automatically when you are linking a C++ program with the appropriate linker options. Whatever language that code is written in, it has whatever declaration of main it needs in order to call it properly.
I was taught that functions need declarations to be called.
Indeed. A function must be declared before it can be called.
why we don't add a declaration for the main function?
Well, you didn't call main function. In fact, you must not call main at all1, so there is never a need to declare main before anything.
Technically though, all definitions are also declarations, so your definition of main also declares main.
Footnote 1: The C++ standard says it's undefined behaviour to call main from within the program.
This allows C++ implementations to put special run-once startup code at the top of main, if they aren't able to have it run earlier from hooks in the startup code that normally calls main. Some real implementations do in fact do this, e.g. calling a fast-math function that sets some FPU flags like denormals-are-zero.
On a hypothetical implementation, calling main could result in fun things like re-running constructors for all static variables, re-initializing the data structures used by new/delete to keep track of allocations, or other total breakage of your program. Or it might not cause any problem at all. Undefined behaviour doesn't mean it has to fail on every implementation.
The prototype is required if you want to call the function, but it's not yet available, like sum in your case.
You must not call main yourself, so there is no need to have a prototype. It's even a bad a idea to write a prototype.
No, the compiler does not need a forward declaration for main().
main() is a special function in C++.
Some important things to remember about main() are:
The linker requires that one and only one main() function exist when creating an executable program.
The compiler expects a main() function in one of the following two forms:
int main () { /* body */ }
int main (int argc, char *argv[]) { /* body */ }
where body is zero or more statements
An additional acceptable form is implementation specific and provides a list of the environment variables at the time the function is called:
int main (int argc, char* argv[], char *envp[]) { /* body */ }
The coder must provide the 'definition' of main using one of these acceptable forms, but the coder does not need to provide a declaration. The coded definiton is accepted by the compiler as the declaration of main().
If no return statement is provided, the compiler will provide a return 0; as the last statement in the function body.
As an aside, there is sometimes confusion about whether a C++ program can make a call to main(). This is not recommended. The C++17 draft states that main() "shall not be used within a program." In other words, cannot be called from within a program. See e.g. Working Draft Standard for C++ Programming Language, dated "2017-03-21", Paragraph 6.6.1.3, page 66. I realize that some compilers support this (including mine), but the next version of the compiler could modify or remove that behavior as the standard uses the term "shall not".
It is illegal to call main from inside your program. That means the only thing that is going to call it is the runtime and the compiler/linker can handle setting that up.This means you do not need a prototype for main.
A definition of a function also implicitly declares it. If you need to reference a function before it is defined you need to declare it before you use it.
So writing the following is also valid:
int sum(int x, int y) {
return x + y;
}
int main() {
std::cout << "The result is " << sum(1, 2);
return 0;
}
If you use a declaration in one file to make a function known to the compiler before it is defined, then its definition has to be known at linking time:
main.cpp
int sum(int x, int y);
int main() {
std::cout << "The result is " << sum(1, 2);
return 0;
}
sum.cpp
int sum(int x, int y) {
return x + y;
}
Or sum could have its origin in a library, so you do not even compile it yourself.
The main function is not used/referenced in your code anywhere, so there is no need to add the declaration of main anywhere.
Before and after your main function the c++ library might execute some init and cleanup steps, and will call your main function. If that part of the library would be represented as c++ code then it would contain a declaration of int main() so that that it could be compiled. That code could look like this:
int main();
int __main() {
__startup_runtime();
main();
__cleanup_runtime();
}
But then you again have the same problem with __main so at some point there is no c++ anymore and a certain function (main) just represents the entry point of your code.
Nope. You can't call it anyway.
You only need forward declarations for functions called before they are defined. You need external declarations (which look exactly like forward declarations on purpose) for functions defined in other files.
But you can't call main in C++ so you don't need one. This is because the C++ compiler is allowed to modify main to do global initialization.
[I looked at crt0.c and it does have a declaration for main but that's neither here nor there].
How can I assign member function which is overloaded to other member function (or function pointer) in C++?
My objective is to wrap member function. I have following code and it doesn't work because it has 2 "Do"s. What I want to do is wrapping Do1 or Do2 to Do with any double * or double **. Hence, I can run only Do and don't need to care about Do1 or Do2. (Maybe, I should specify condition that need to be chosen between Do1 and Do2.)
class Sample {
int (*Do)(double *arr);
int (*Do)(double **arr);
int Do1(double *arr);
int Do1(double **arr);
int Do2(double *arr);
int Do2(double **arr);
};
Or do you have any suggestions for this objective?
Addition : For Thomas, function objects(functors) is a good idea, but it only resolves overloading. I want to choose function (ex, Do1 or Do2). I have several prescribed functions and I can make choose one of them to Do. However, I also want to assign custom function to Do.
For example when I run Do, I could run Do1, Do2, or my own new customized function. (I should set what function will be executed when I make a instance)
and.. I can't use C++11 in my situation. (I want to, but my server has a older GCC versions)
Your code is ill-formed and will NOT compile. You can overload function, but not objects! That is, you cannot have two pointers named 'Do' with different types. I can't recall perfectly, but MSVC would tell you something like this:
'Sample::Do' : redefinition; different basic types
If you want to do something like that, you can use flag:
class Sample
{
int Do(double *arr);
int Do(double **arr);
int Do1(double *arr);
int Do1(double **arr);
int Do2(double *arr);
int Do2(double **arr);
void SetDoVersion(int version);
int _do_version;
};
And 'Do' would look like this:
int Sample::Do(double *arr)
{
//For more than 2-3 versions you could also use switch().
if(this->_do_version == 1)
return this->Do1(arr);
else
return this->Do2(arr);
}
int Sample::Do(double **arr)
{
//same as above
}
SetDoVersion() sets currently 'installed' version:
void Sample::SetDoVersion(int version)
{
this->_do_version = version;
}
This is probably the simplest solution for this task.
I made a header file sampleheader.h with following code:
namespace sample_namespace
{
int add(int n1,int n2)
{
return (n1 + n2);
}
}
Now my main.cpp file is:
#include <iostream>
#include "sampleheader.h"
using namespace std;
int add(int n1, int n2)
{
return (n1 + n2);
}
int main(void)
{
using namespace sample_namespace;
//cout<<add(5,7);
}
The project is built with no warning if i leave that line commented.It is understandable because the local add() function is defined in the global scope and add() function is made visible in the scope of main(). So no name conflict happens.
However, if I remove the comments, I get the following error:
"Ambiguous call to overloaded function"
First of all there should be no name conflict at all as explained by me above (if I'm right). But, if at all there is a name conflict why is it that it is notified by compiler only when I call the function. Such type of error should be shown as soon as a name conflicts (if at all).
Any help is appreciated.
Well, you explained it yourself.
When you have both int add() and int sample_namespace::add() in scope, the call is ambiguous. The statement add() could mean either of them.
There is no conflict in the functions co-existing because one is int add() and the other is int sample_namespace::add(). This is the entire purpose of namespaces.
You just have to be clear when you write code that uses them. If you get rid of your using namespace directives and always write explicit code, then you won't run into a problem:
#include <iostream>
namespace sample_namespace {
int add(int n1, int n2) {
return (n1 + n2);
}
}
int add(int n1, int n2) {
return (n1 + n2);
}
int main() {
std::cout << sample_namespace::add(5,7);
}
(Also, defining non-inline functions in headers is A Bad Idea™.)
"using namespace" does not hide other implementations. What it does in this case is make it ambiguous.
You have both sample_namespace::add and ::add with the same signature. Since you don't explicitly say which one to use, the compiler can't tell.
Declaring both functions is legal and unambiguous (which is why the compiler only complains when you use the function).
The reason why it's legal to declare both functions like that is because you can call both unambiguously, by qualifying them. That's why you get an error only when you make an unqualified call. Up to that point, there is not even a theoretical problem.
Intentionally, using namespace X; shouldn't introduce ambiguity errors by itself. That would very much defeat the purpose of namespaces. The common using namespace std; introduces many names that you'd reasonbly define yourself as well.
You cannot shadow symbols like that, only variable names (which is a warning on most compilers, i.e. a bad idea). using directives aren't precise in any sense, which I think is the assumption that most people make.
using directives will import a symbol into the scope. for instance, you can do things like this:
namespace foo {
using namespace std;
}
foo::string val;
This sort of practice leads to some very annoying compiler errors to track down. Your simple example is clear where the error is. If you try doing it in a few hundred thousand lines of code, you will be much less pleased.
I would advise you not to acquire the habit of relying on the using directive. If you must, just do one type at a time.
using std::string;
Basically, this keeps you honest. And if there is a naming conflict, grep will take 30 seconds to uncover where the problem is.
If you just spend a couple weeks typing std:: in front of your types, you will get used to it. I promise that the amount of time you think you are saving is greatly exaggerated.
I think this is because of compiler-optimisation. When your string is commented - he saw, that there are some function, but you don't use it, so he discard it. And when he saw that function useful - he want to insert function call, but can't chose which one you want.
I need help making an c++ program with a function that uses int Disc(int A, int B, int C) and calculates returns B*B-4*A*C and use the function Disc in the program..... i have this so far.
void main(){
cout << Disc(a,b,c);
}
What does the book you are using say about functions?
Assuming you can't get a book, take a look that this tutorial on functions (See the edit below)
You already have the function definition. The name, what parameters it takes and what it returns so if you take some time looking at the above tutorial you should be able to put something together (All you need to do is to write the body of the function).
The one thing that may cause you an issue (compiler error) is if you don't put it above the main function as either the function definition or the function itself must come before it is used. For simplicity at this point I reccomend you just put the function itself above the main function as shown in first example in the tutorial I linked to.
EDIT about linked tutorial
It suggests you use return with brackets. Example:
return (5);
Where as it should be used without them. Example:
return 5;
Ok, so you define the function Disc then:
int Disc(int A, int B, int C)
{
/* tricky part goes here... */
}