It would seem I can declare a function at block scope:
int main()
{
void f(); // OK
}
However I can't define it:
int main()
{
void f() {}; // ERROR
}
My question is, of what use is a function declaration at block scope? What is a use case?
It's sometimes a shortcut to declaring and calling an externally-linked function which itself isn't publically defined in a header. For example, imagine you were linking against a C library which you knew provided a LibDebugOn(int) call but hadn't defined it in a header. It can be a shortcut to declare and call it in one place:
void myFunc() {
// call "Lib" but turn on debugging via hidden API
extern "C" void LibDebugOn(int); // declare hidden C-linked function
LibDebugOn(1); // call it
// do something with the library here...
LibDebugOn(0); // turn off lib debugging now
}
In fairness this is usually only worthwhile for a one-off quick hack, and not something to be encouraged.
You can define it. http://ideone.com/kJHGoF
#include <cstdio>
int main()
{
void f(); // Forward declare function named "f" returning void in the
// global namespace.
f();
}
/*
void g()
{
f(); // ERROR!
}
*/
void f()
{
std::puts("hello!");
}
I'm not sure why someone would actually want to use this. It is in the language this way for backwards compatibility with C; but I've got no idea what someone would do with this in C.
Related
Is there a way to avoid the Graph:: repetition in the implementation file, yet still split the class into header + implementation? Such as in:
Header File:
#ifndef Graph_H
#define Graph_H
class Graph {
public:
Graph(int n);
void printGraph();
void addEdge();
void removeEdge();
};
#endif
Implementation File:
Graph::Graph(int n){}
void Graph::printGraph(){}
void Graph::addEdge(){}
void Graph::removeEdge(){}
I'm guessing this is to avoid lots of "unnecessary typing". Sadly there's no way to get rid of the scope (as many other answers have told you) however what I do personally is get the class defined with all my function prototypes in nice rows, then copy/paste into the implementation file then ctrl-c your ClassName:: on the clip board and run up the line with ctrl-v.
If you want to avoid typing the "Graph::" in front of the printGraph, addEdge etc., then the answer is "no", unfortunately. The "partial class" feature similar to C# is not accessible in C++ and the name of any class (like "Graph") is not a namespace, it's a scope.
No there's not. Not directly at least. You could go for preprocessor tricks, but don't do it.
#define IMPL Graph::
IMPL Graph(int n){}
void IMPL printGraph(){}
void IMPL addEdge(){}
void IMPL removeEdge(){}
Also, you shouldn't even want to do it. What's the point. Besides it being a C++ rule, it lets you know you're actually implementing a member function.
One option is using. If you have method definitions which are in a cpp file that never gets #included, then using is safe (doesn't affect other files):
foo.h:
class FooLongNameSpecialisationsParamaters
{
int x_;
public:
int Get () const;
void Set (int);
};
foo.cpp:
#include "foo.h"
using Foo = FooLongNameSpecialisationsParamaters;
int Foo::Get () const
{
return x_;
}
void Foo::Set (int x)
{
x_ = x;
}
main.cpp:
#include "foo.h"
int main ()
{
//Foo foo; <-- error
FooLongNameSpecialisationsParamaters foo;
return 0;
}
No, there is no way to avoid it. Otherwise, how would you know if a given function definition is for a class function or for a static function?
If you are asking if you can define a member function such as Graph::printGraph without specifying the class name qualification, then the answer is no, not the way that you want. This is not possible in C++:
implementation file:
void printEdge(){};
The above will compile just fine, but it won't do what you want. It won't define the member function by the same name within the Graph class. Rather, it will declare and define a new free function called printEdge.
This is good and proper, if by your point of view a bit of a pain, because you just might want two functions with the same name but in different scopes. Consider:
// Header File
class A
{
void foo();
};
class B
{
void foo();
};
void foo();
// Implementation File
void foo()
{
}
Which scope should the definition apply to? C++ does not restrict you from having different functions with the same names in different scopes, so you have to tell the compiler what function you're defining.
//yes it is possible using preprocessor like this:
#define $ ClassName //in .cpp
void $::Method1()
{
}
//or like this: in the header .h:
#undef $
#define $ ClassName'
// but you have to include the class header in last #include in your .cpp:
#include "truc.h"
#include "bidule.h" ...
#include "classname.h"
void $::Method() { }
//i was using also
#define $$ BaseClass
//with single inheritance than i can do this:
void $::Method()
{
$$::Method(); //call base class method
}
//but with a typedef defined into class like this it's better to do this:
class Derived : Base
{
typedef Base $$;
}
EDIT: I misread your question. This would be an answer to the question whether you can split header-files. It doesn't help you to avoid using LongClassName::-syntaxes, sorry.
The simple answer: You can split up c++-file, but you can not split up header-files.
The reason is quite simple. Whenever your compiler needs to compile a constructor, it needs to know exactly how many memory it needs to allocate for such an object.
For example:
class Foo {
double bar; //8 bytes
int goo; //4 bytes
}
new Foo() would require the allocation of 12 bytes memory. But if you were allowed to extend your class definitions over multiple files, and hence split header files, you could easily make a mess of this. Your compiler would never know if you already told it everything about the class, or whether you did not. Different places in your code could have different definitions of your class, leading to either segmentation faults or cryptic compiler errors.
For example:
h1.h:
class Foo {
double bar; // 8 bytes
int goo; // 4 bytes
}
h2.h:
#include "h1.h"
class Foo {
double goo; // 8 bytes
} // we extend foo with a double.
foo1.cpp:
#include "foo1.h"
Foo *makeFoo() {
return new Foo();
}
foo2.cpp:
#include "foo2.h"
void cleanupFoo(Foo *foo) {
delete foo;
}
foo1.h:
#include "h1.h"
Foo *makeFoo();
foo2.h:
#include "h1.h"
#include "h2.h"
void cleanupFoo(Foo *foo)
main.cpp:
#include foo1.h
#include foo2.h
void main() {
Foo *foo = makeFoo();
cleanupFoo(foo);
}
Carefully check what happens if you first compile main.cpp to main.o, then foo1.cpp to foo1.o and foo2.cpp to foo2.o, and finally link all of them together. This should compile, but the makeFoo() allocates something else then the cleanupFoo() deallocated.
So there you have it, feel free to split .cpp-files, but don't split up classes over header files.
I have a function foo() that updates a global CAtlList. Now I want to reuse foo to update another list. Currently I achieve this using a default argument.
//header.h
extern CAtlList<data> globalList;
void foo(CAtlList<data> &somelist = globalList);
//file1.cpp
CAtlList<data> globalList;
void foo(CAtlList<data> &somelist)
{
//update somelist
}
//file2.cpp
#include "header.h"
foo();
and
CAtlList<data> anotherList;
foo(anotherList);
//use anotherList
But for the default scenario foo takes globalList by reference, which means globalList must be visible at the point of declaration. I had to expose and add an extern declaration of globalList for that to happen.
I'd rather not expose it, is it at all possible?
Use an overload, not a default parameter.
void foo();
void foo(CAtlList<data> &somelist);
It costs you 4 short lines of code in the .cpp: The body of the parameterless foo calling the 1-parameter foo with the correct argument. That's the total cost to get the expressiveness you desire. A default parameter is not the tool for your job.
I don't know you can avoid declaring a variable that's referenced as a default. However, you could simply overload the function:
//file1.h
void foo();
void foo(CAtlList<data> &somelist);
//file1.cpp
#include "file2.h"
CAtlList<data> globalList; // Local scope only
void foo(CAtlList<data> &somelist)
{
//update somelist
}
void foo()
{
foo(globalList);
}
A more modern way is to use the 'optional' class that's part of the C++ library:
http://en.cppreference.com/w/cpp/utility/optional
//file1.h
#include <optional>
void foo(optional<CAtlList<data>> &somelist);
//file1.cpp
#include "file1.h"
CAtlList<data> globalList; // Local scope only
void foo(optional<CAtlList<data>> &somelist){
if (somelist.has_value()) { /* update somelist */ }
else { /* update globalList */ }
}
However, I suspect that this will break the existing dependencies. If there are few and easy to fix, this is probably the way.
The other comments are also correct. You should try and avoid the use of global state wherever possible - its a symptom of poor design.
I saw this question and I tried to do as the answer to that question said. To use the extern keyword in the header file to define an array and then declare it outside of that namespace or class in a other cpp file.
It didn't work for me really, I'm not sure if it because I'm using a void pointer array (i.e void* array[]) or if it's just my ignorance that prevents me from seeing the problem.
This is the shortest example I can come up with:
[cpp.cpp]
#include "h.h"
void main(){
void* a::b[] = {
a::c = a::d(1)
};
}
[h.h]
namespace a{
struct T* c;
struct T* d(int e);
extern void* b[];
}
So the problem is that I receive the error:
IntelliSense: variable "a::b" cannot be defined in the current scope
And I have no clue why that is.
First, you should declare main() as int ! See here why.
Declaring your array as extern in a namespace means that it belongs to the namespace but is defined somewhere ele, normally in a separate compilation unit.
Unfortunately, in your main(), you try to redefine the element as a local variable. This explains the error message you receive.
You shoud do as follows:
#include "h.h"
void* a::b[] { a::c, a::d(1) }; // global variable belonging to namespace
int main() // int!!!
{
/* your code here */
}
The code will compile. The fact that a::b[] is defined in the same compiling unit is accepted. But the linker will complain because a::d(1) is a call to the function d returning a pointer to a struct, and this function is defined nowhere.
Therfore you should also define this:
namespace a {
struct T* d(int e)
{
return nullptr; // in reality you should return a pointer to struct T
}
}
Interestingly, struct T does not need to work for this code to compile and link.
Is there a way to avoid the Graph:: repetition in the implementation file, yet still split the class into header + implementation? Such as in:
Header File:
#ifndef Graph_H
#define Graph_H
class Graph {
public:
Graph(int n);
void printGraph();
void addEdge();
void removeEdge();
};
#endif
Implementation File:
Graph::Graph(int n){}
void Graph::printGraph(){}
void Graph::addEdge(){}
void Graph::removeEdge(){}
I'm guessing this is to avoid lots of "unnecessary typing". Sadly there's no way to get rid of the scope (as many other answers have told you) however what I do personally is get the class defined with all my function prototypes in nice rows, then copy/paste into the implementation file then ctrl-c your ClassName:: on the clip board and run up the line with ctrl-v.
If you want to avoid typing the "Graph::" in front of the printGraph, addEdge etc., then the answer is "no", unfortunately. The "partial class" feature similar to C# is not accessible in C++ and the name of any class (like "Graph") is not a namespace, it's a scope.
No there's not. Not directly at least. You could go for preprocessor tricks, but don't do it.
#define IMPL Graph::
IMPL Graph(int n){}
void IMPL printGraph(){}
void IMPL addEdge(){}
void IMPL removeEdge(){}
Also, you shouldn't even want to do it. What's the point. Besides it being a C++ rule, it lets you know you're actually implementing a member function.
One option is using. If you have method definitions which are in a cpp file that never gets #included, then using is safe (doesn't affect other files):
foo.h:
class FooLongNameSpecialisationsParamaters
{
int x_;
public:
int Get () const;
void Set (int);
};
foo.cpp:
#include "foo.h"
using Foo = FooLongNameSpecialisationsParamaters;
int Foo::Get () const
{
return x_;
}
void Foo::Set (int x)
{
x_ = x;
}
main.cpp:
#include "foo.h"
int main ()
{
//Foo foo; <-- error
FooLongNameSpecialisationsParamaters foo;
return 0;
}
No, there is no way to avoid it. Otherwise, how would you know if a given function definition is for a class function or for a static function?
If you are asking if you can define a member function such as Graph::printGraph without specifying the class name qualification, then the answer is no, not the way that you want. This is not possible in C++:
implementation file:
void printEdge(){};
The above will compile just fine, but it won't do what you want. It won't define the member function by the same name within the Graph class. Rather, it will declare and define a new free function called printEdge.
This is good and proper, if by your point of view a bit of a pain, because you just might want two functions with the same name but in different scopes. Consider:
// Header File
class A
{
void foo();
};
class B
{
void foo();
};
void foo();
// Implementation File
void foo()
{
}
Which scope should the definition apply to? C++ does not restrict you from having different functions with the same names in different scopes, so you have to tell the compiler what function you're defining.
//yes it is possible using preprocessor like this:
#define $ ClassName //in .cpp
void $::Method1()
{
}
//or like this: in the header .h:
#undef $
#define $ ClassName'
// but you have to include the class header in last #include in your .cpp:
#include "truc.h"
#include "bidule.h" ...
#include "classname.h"
void $::Method() { }
//i was using also
#define $$ BaseClass
//with single inheritance than i can do this:
void $::Method()
{
$$::Method(); //call base class method
}
//but with a typedef defined into class like this it's better to do this:
class Derived : Base
{
typedef Base $$;
}
EDIT: I misread your question. This would be an answer to the question whether you can split header-files. It doesn't help you to avoid using LongClassName::-syntaxes, sorry.
The simple answer: You can split up c++-file, but you can not split up header-files.
The reason is quite simple. Whenever your compiler needs to compile a constructor, it needs to know exactly how many memory it needs to allocate for such an object.
For example:
class Foo {
double bar; //8 bytes
int goo; //4 bytes
}
new Foo() would require the allocation of 12 bytes memory. But if you were allowed to extend your class definitions over multiple files, and hence split header files, you could easily make a mess of this. Your compiler would never know if you already told it everything about the class, or whether you did not. Different places in your code could have different definitions of your class, leading to either segmentation faults or cryptic compiler errors.
For example:
h1.h:
class Foo {
double bar; // 8 bytes
int goo; // 4 bytes
}
h2.h:
#include "h1.h"
class Foo {
double goo; // 8 bytes
} // we extend foo with a double.
foo1.cpp:
#include "foo1.h"
Foo *makeFoo() {
return new Foo();
}
foo2.cpp:
#include "foo2.h"
void cleanupFoo(Foo *foo) {
delete foo;
}
foo1.h:
#include "h1.h"
Foo *makeFoo();
foo2.h:
#include "h1.h"
#include "h2.h"
void cleanupFoo(Foo *foo)
main.cpp:
#include foo1.h
#include foo2.h
void main() {
Foo *foo = makeFoo();
cleanupFoo(foo);
}
Carefully check what happens if you first compile main.cpp to main.o, then foo1.cpp to foo1.o and foo2.cpp to foo2.o, and finally link all of them together. This should compile, but the makeFoo() allocates something else then the cleanupFoo() deallocated.
So there you have it, feel free to split .cpp-files, but don't split up classes over header files.
This is a small program :
#include <iostream>
using namespace std;
int main() {
f();
system("pause");
}
void f() {
static int x = 20 ;
class tester {
public :
tester() {
cout << x ;
}
} x1;
}
The error that i get here is :error C3861: 'f': identifier not found
If i place the function f above main I will get the desired output.
Why it is so ?
I was told that program execution begins at main. According to this the code should run in the first case also.
How does the compiler start reading the program?
The beginning of the compilation and the beginning of the execution of the program are two different things.
The execution starts from the main.
The compilation begins from the beginning of the file; the compiler don't "jump around" the file to find the needed pieces, but it reads the input in a linear fashion (I suspect that this related, among the other things, to the fact that the C++ grammar is really complicated).
When the compiler is at some point in parsing the file, it only knows what has been declared/defined up to that point1.
Because of this, function prototypes (and non-defining declarations in general) have been invented: the prototypes of all the functions defined in the file are put at the beginning of the file, typically after the #include directives or in a separated include file. The prototypes tell to the compiler that such functions will be defined later, and what is the function signature (i.e. name, parameters, return value).
The prototype is made as a normal function, but without the body, which is replaced by a semicolon2. For example, in your code you would write
void f();
before the main.
IIRC there are some relaxations to this rule that allow the compiler to "wait" for some declarations to make some template magic work, but this is not relevant here.
In a prototype is also common not to write the names of the parameters, leaving just their type (this can be done also in function definitions, but it doesn't make much sense there unless you have a formal parameter you don't use). Still, I prefer to leave the parameter names there as a form of documentation.
I was told that program execution begins at main.
And that's exactly the point.
The compiler starts from main, and then sees a call to f(), which it has not encountered so far (as it is defined afterwards), so it does not know what to do with it.
If you want to define f after main you can place a function prototype before, such as
#include <iostream>
using namespace std;
void f(); // <--- This tells the compiler that a function name f will be defined
int main() {
f();
system("pause");
}
void f() {
static int x = 20 ;
class tester {
public :
tester() {
cout << x ;
}
} x1;
}
To be able to call a function it must have been declared at some earlier point in the code. This is just a rule of the language designed to help compilers.
You can declare the function earlier with e.g.
void f();
...and then define it after main as you have done.
The compiler starts at the top and reads down to the bottom.
you'll need to have something like:
#include <iostream>
using namespace std;
void f();
int main() {
f();
system("pause");
}
void f() {
static int x = 20 ;
class tester {
public :
tester() {
cout << x ;
}
} x1;
}
No, the compiler needs to see at least a declaration of f() before it is used. A c(++) code file is a simple text file and must be read from begin to end by the compiler.
During the compilation process, when the compiler is evaluating main() it needs to know what f() is in advance to be able to generate the correct assembly code to call this function. That's why you need to put it before main() in this case.
As an alternative you can declare the prototype of f() before main() so the compiler knows it's a local function declared somewhere else on your file:
void f(); // prototype
int main()
{
// .. code ..
}
void f() // implementation of f()
{
// .. code ..
}