So, this problem, for some reason it shows me this error (ubuntu, terminal, g++). I searched the net and didn't show anything similar to mine. The code is (gfdz.cpp)
#include <iostream>
#include <string>
using namespace std;
struct dynmass
{
unsigned long int vm; //вместимость
unsigned long int el; //количество элементов
};
int *i,*q;
void create()
{
dynmass a;
a.vm = 0;
a.el = 0;
i = new int[0];
extern "a"
{
void push();
void remuve();
int kolichestvo();
int vmestimostb();
int main;
};
}
What you have there is a language linkage specification. And within it, you have a bunch of function declarations.
A language specifications can only appear in namespace scope. Yours is in the block scope, so that's what's wrong with it. Also, "a" language linkage is not supported by standard c++ so you may need to consult your compiler manual to find out if it's supported.
Related
The following program compiles as a C program:
#include <stdlib.h>
#include <stdio.h>
void f(int n, int m, int x[n][m]) {
printf("x[0][2] = %i\n",x[0][2]);
}
int main() {
int v[][3] = { {0,1,2}, {3,4,5} };
f(2,3,v);
}
However, when compiled as C++ with g++, I have:
main.c:4:29: error: use of parameter outside function body before ‘]’ token
void f(int n, int m, int x[n][m]) {
^
It seems that this feature of C does not exist in C++. Is there any flag that can be given to g++ so that it accepts the code?
It seems that this feature of C does not exist in C++.
Correct.
Is there any flag that can be given to g++ so that it accepts the code?
No, there is no such feature allowing a VLA as part of a parameter list. You will have to compile the code as C.
Other similar gcc extensions exist, see: https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html
main:
#include <iostream>
#include "common.h"
#include "squares.h"
#include "board.h"
using namespace std;
int Board::board_length=8;
int main()
{
Board *tabla=new Board();
tabla->printBoard();
}
board.h :
#ifndef BOARD_H
#define BOARD_H
#include "squares.h"
class Board
{
static int board_length;
Square boardSquares[board_length][board_length];
public:
Board();
void printBoard();
};
error line 8 in board.h
C:\c++ projects\CHESS-P3\board.h|8|error: array bound is not an integer constant before ']' token|
As the error message indicates, board_length is not a constant value. To fix that, change the line
static int board_length;
in board.h to
static const int board_length = 8;
and remove the line
int Board::board_length=8;
from your main file. This should compile, but I cannot tell for sure, since you did not provide a minimal, reproducible example.
Bonus: To avoid a memory leak you should also change
Board *tabla=new Board();
tabla->printBoard();
in main just to
Board tabla;
tabla.printBoard();
Since you do not seem to be passing the Board instance around, there is no need to use a pointer here.
As a general rule of thumb: Whenever there is a new somewhere, there also needs to be a corresponding delete. Otherwise your pogram may leak memory. While this is no big deal for a small, short-running example program, it can become a serious issue for a program that runs for a long time.
This is a nice use case for an int template:
board.h
template<int _board_length>
class Board
{
static const int board_length = _board_length;
int boardSquares[_board_length][_board_length];
public:
Board(){};
void printBoard(){};
};
main.cpp
...
constexpr int BL=8;
//odr declare the static member if it matters
template<>
const int Board<BL>::board_length;
int main() {
Board<BL> tabla;
tabla.printBoard();
}
That way, the actual dimensions of the array are defined in the main and not in the include file where the class is declared, and all the methods in Board can know the actual size.
This question has derived from this one.
I have a working program which must be split into multiple parts. In this program is needed to use a variable (now it's a GTK+ one :P) many times in parts of the program that will end up in separated .cpp files.
So, I made a simple example to understand how to make variables available to the program parts. A modified version of the previous code would be:
#include <iostream>
using namespace std;
int entero = 10;
void function()
{
cout<<entero<<endl;
//action1...;
}
void separated_function()
{
cout<<entero<<endl;
//action2...;
}
int main( int argc, char *argv[] )
{
function();
separated_function();
cout<<entero<<endl;
//something else with the mentioned variables...;
return 0;
}
It is needed to split the code correctly, to have function(), another_function() and main() in separated .cpp files,and make entero avaliable to all of them... BUT:
In the previous question #NeilKirk commented:Do not use global variables. Put the required state into a struct or class, and pass it to functions as necessary as a parameter (And I also have found many web pages pointing that is not recommended to use global variables).
And, as far I can understand, in the answer provided by #PaulH., he is describing how to make variables avaliable by making them global.
This answer was very useful, it worked fine not only with char arrays, but also with ints, strings and GTK+ variables (or pointers to variables :P).
But since this method is not recommended, I would thank anyone who could show what would be the correct way to split the code passing the variables as a function parameter or some other method more recommended than the - working - global variables one.
I researched about parameters and classes, but I'm a newbie, and I messed the code up with no good result.
You need to give the parameter as a reference if you want the same comportement as a global variable
#include <iostream>
using namespace std;
// renamed the parameter to avoid confusion ('entero' is valid though)
void function(int &ent)
{
cout<<ent<<endl;
++ent; // modify its value
//action1...;
}
void separated_function(int &ent)
{
cout<<ent<<endl;
++ent; // modify its value again
//action2...;
}
int main( int argc, char *argv[] )
{
int entero = 10; // initializing the variable
// give the parameter by reference => the functions will be able to modify its value
function(entero);
separated_function(entero);
cout<<entero<<endl;
//something else with the mentioned variables...;
return 0;
}
output:
10
11
12
Defining a class or struct in a header file is the way to go, then include the header file in all source files that needs the classes or structures. You can also place function prototypes or preprocessor macros in header files if they are needed by multiple source files, as well as variable declarations (e.g. extern int some_int_var;) and namespace declarations.
You will not get multiple definition errors from defining the classes, because classes is a concept for the compiler to handle, classes themselves are never passed on for the linker where multiple definition errors occurs.
Lets take a simple example, with one header file and two source files.
First the header file, e.g. myheader.h:
#ifndef MYHEADER_H
#define MYHEADER_H
// The above is called include guards (https://en.wikipedia.org/wiki/Include_guard)
// and are used to protect the header file from being included
// by the same source file twice
// Define a namespace
namespace foo
{
// Define a class
class my_class
{
public:
my_class(int val)
: value_(val)
{}
int get_value() const
{
return value_;
}
void set_value(const int val)
{
value_ = val;
}
private:
int value_;
};
// Declare a function prototype
void bar(my_class& v);
}
#endif // MYHEADER_H
The above header file defines a namespace foo and in the namespace a class my_class and a function bar.
(The namespace is strictly not necessary for a simple program like this, but for larger projects it becomes more needed.)
Then the first source file, e.g. main.cpp:
#include <iostream>
#include "myheader.h" // Include our own header file
int main()
{
using namespace foo;
my_class my_object(123); // Create an instance of the class
bar(my_object); // Call the function
std::cout << "In main(), value is " << my_object.get_value() << '\n';
// All done
}
And finally the second source file, e.g. bar.cpp:
#include <iostream>
#include "myheader.h"
void foo::bar(foo::my_class& val)
{
std::cout << "In foo::bar(), value is " << val.get_value() << '\n';
val.set_value(456);
}
Put all three files in the same project, and build. You should now get an executable program that outputs
In foo::bar(), value is 123
In main(), value is 456
I prefer to provide a functional interface to global data.
.h file:
extern int get_entero();
extern void set_entero(int v);
.cpp file:
static int entero = 10;
int get_entero()
{
return entero;
}
void set_entero(int v)
{
entero = v;
}
Then, everywhere else, use those functions.
#include "the_h_file"
void function()
{
cout << get_entero() << endl;
//action1...;
}
void separated_function()
{
cout << get_entero() << endl;
//action2...;
}
int main( int argc, char *argv[] )
{
function();
separated_function();
cout<< get_entero() <<endl;
//something else with the mentioned variables...;
return 0;
}
If you do not plan to modify the variable, it is generally ok to make it global. However, it is best to declare it with the const keyword to signal the compiler that it should not be modified, like so:
const int ENTERO = 10;
If you are using multiple cpp files, also consider using a header file for your structures and function declarations.
If you are planning on modifying the variable, just pass it around in function parameters.
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.
I'm learning C++ now. What are the complete legal entities that can be put in a namespace?
Legal entities here means valid members of a namespace
Oh, this is a real question. I'm coming from .net and I have the .net mindset.
Any code can be put inside namespace.
However main() function must be at global namespace. It cannot be put inside user-defined namespace.
namespace userns
{
int main()
{
return 0;
}
}
This program wouldn't compile link : http://www.ideone.com/k6SPc
Its because userns::main() will not be considered entry-point of the program; it became just like any other user function, not the standard main(). To compile it successfull, you've to add main() at global namespace:
namespace userns
{
int main()
{
return 0;
}
}
int main()
{
return 0;
}
This will compile link now : http://www.ideone.com/76Ynu
Anything can be put in a namespace (which is legal for C++, of course).
Actually, everything is in some namespace - the global namespace, if not specified.
Everything can be put in namespace except few "entities", which will not compile.
(1) Globally overloaded operator new and operator delete
namespace N
{
void* operator new (size_t size) // error
{ ... }
}
(2) Definition of the constructs which are declared in outer scope of the namespace; for example you have a class A declared globally then you cannot define its method inside your namespace N. In the same way, if you have method declared in a namespace N then you cannot put its definition inside namespace N::Nested (i.e. Nested is a namespace inside N).
//file
struct A {
void foo ();
static int i;
};
namespace N
{
int A::i = 0; // error
void A::foo() // error
{}
}
Demo: this is not allowed.
I remember at least these 2 restrictions from my experience. Don't know about specs.