I'm writing code in Visual C++ and I need to use a global variable. I know it's generally not a good idea, but in this case, it is necessary. I have created the variable and it is accessible from the function that needs it, but I can't figure out how to give it an initial value.
in the .h file it looks like
extern int lversion;
and in the .cpp file it looks like
int lversion;
How can I give this variable an initial value of 0?
Adding these two lines in your .h and .cpp files respectively will allow you to initialize a global variable.
.h:
extern int Val;
.cpp:
int Val = 0;
The variable does have initial value 0 as it is. Globals and statics are value-initialized unless otherwise specified. (for an int, it will be 0)
If you want any other value, you can specify it:
In the cpp file:
int lversion= 3;
or
int lversion(3);
but for a value of 0 there's no point being this verbose.
Related
Is it possible to code a library with a parameter that will be defined by the user at compile time without modifying the library?
Library:
test.h
#ifndef TEST_H
#define TEST_H
#define MAX_NB USER_DEF
void myFunc();
#endif
test.cpp
#include "test.h"
int arr[MAX_NB] = {0};
void myFunc() {
for (int i = 0: i < MAX_NB; i++ ) {
// DO SOMETHING
}
}
And the main code:
#define USER_DEF 5
#include "test.h"
void main() {
while (1) {
myFunc();
}
}
I suppose I am getting an error (USER_DEF not declared in this scope) because USER_DEF is not defined in the translation unit containing test.h and test.c, but I hope there is a way to do it, but I can't find it.
My goal is to have an array with a user-defined size (code modified).
The answer is that it doesn't make sense to use variable-sized arrays for a very restricted 8-bit system with very limited RAM.
Instead you should have a fixed size array of n bytes. Let the user pick a number, then ensure that it is less or equal to n. Then keep track of the used size with a plain integer variable. You must always reserve memory for the worst case.
The array must have static storage duration, since it will be too large to be allocated on the stack.
I'd usually go and suggest to check out the templates, although, you can create user-defined variables, they are called function parameters. Please take a look
To sum it up, this is not what you call user-defined variable, because this is defined by the programmer, not by the user of the program. This is called a constant, whatsoever. If you want to create a compile-time constant, defined by you, you can take a look at constexpr.
Also, let me explain to you why this doesn't work correctly. You guessed correctly, it's because it is not defined into the header file, but why? Because headers come first and then comes the main file. The header searches for the defined constant and fails to find it, and that is the reason why you get the USER_DEF not declared in this scope.
I am working on a homework assignment, and I have almost everything done except for this obnoxious static value that our professor wishes us to use: value
The header file contains:
private:
static int value;
And we have to have a function calculate the value, like so:
static void calculate()
{
long a = 1L;
int count = 0;
while( a != 0 )
{
a = a << 1;
count++;
}
value = count;
}
This is essentially calculating the number of bits in a long, using bit shifting.
However, I am getting the error " undefined reference to `Class1::value'
I've spent the last hour and a half figuring this out, and it's killing me. Any help would be great, all searches have come up dead.
Thanks!
Update:
I included
int Class1::value = 0;
However, now I am getting an error saying "error: int Class1::value is private
In your *.cpp file add
int ClassName::value = 0;
This will allocate storage for a value.
The piece of code that you actually have in a class declaration just declares this variable (makes the compiler aware that such a variable exists). However, each variable must be declared and defined. A definition will make sure the storage is put aside for this variable and create a symbol your compiler was unable to find before.
You need to define a static data member in (.cpp) source file with following syntax:
datatype Your_ClassName::variable;
I am trying to convert an old Fortran 77 code to C++ and most of the variables are declared in Common blocks such as:
COMMON/BLK1/Gw(200),Eta(4096),t(4096),Phi(200),w(200)
COMMON/BLK2/g,dw,Vel,M,dt,N,Ioutp1,Ioutp2
COMMON/BLK3/Hs,Std,E,Hs1,Tdt
As I understand it, common blocks are used simply to make variables accessible throughout the program in different subroutines. Therefore, in a C++ program, would I be able to create structs with the variables (outside of the main) and call the variables this way as members of the struct?
Based on my understanding of COMMON from this page, the C++ equivalent would be to make a file called common.h (with include guards) that contains:
namespace BLK1
{
int const Gw = 200;
int const Eta = 4096;
int const t = 4096;
int const Phi = 200;
int const w = 200;
}
namespace BLK2
{
extern int g, dw, Vel, M, dt, N, Ioutp1, Ioutp2;
}
namespace BLK3
{
extern int Hs, Std, E, Hs1, Tdt;
}
Also, in exactly one .cpp file in your project you need to provide a definition for any non-consts, e.g. in foo.cpp:
#include "common.h"
namespace BLK2
{
int g, dw, Vel, M, dt, N, Ioutp1, Ioutp2;
}
namespace BLK3
{
int Hs, Std, E, Hs1, Tdt; // initialized to 0 by default
}
You may want to use a different type than int, e.g. unsigned long. I'm assuming the initialized values are meant to be const; if not then change int const to extern int and remove the initializer. The initializer would have to go in the definition in the .cpp file.
Avoid the mistake of declaring a non-const, non-extern variable in the header; this causes undefined behaviour if the header is included in two different units.
You access these variables by writing BLK1::Eta for example.
As you surmise it might be considered tidier to use a struct instead of a namespace, although you'd still have to create an instance of the struct which is declared extern in the header, and defined in exactly one .cpp file; and if you are pre-C++11 it's more annoying to provide initializers.
(Of course, even better would be to refactor the code to not use globals. But it might be useful as a first pass to do a direct translation).
Common blocks with the same name overlap each other in memory. You can allocate a chunk of memory, and typecast pointers to it. Another option is to declare them in a union. That is why a union was invented. Certainly once your union is set up, you use extern in the other modules.
Put the following into a common header and an instance of it into module 1.
Add an extern so it can be seen in module 2.
union blk1
{
struct module_1_view
{
double gw(200);
double eta(4096);
double t(4096);
double phi(200);
double w(200);
}
struct module_2_view
{
double parameters(8592); // 200 + 4096 + 4096 + 200
double w_status(200);
}
}
Imagine module 1 being responsible for loading some set of doubles from a file into the the variables in the module_1_view. Once those parameters are loaded and validated, module 2 is called, which accesses the parameters from the module 2 view. Nearly all of them are accessed via the parameters variable, except for the w_status, which is actually 200 indicators that indicate something about the success or validation of the parameters.
The key point is that module 1 and 2 access the same chunk of memory (hence the union) and they use their own set of variable names.
I can't speak directly to Fortran, but if you want to make a variable accessible throughout the entire program in c/c++, extern is the keyword you are looking for.
Extern is a C style way of sharing data. C++ would push you into OO design, of which a variable that is tightly coupled to many objects isn't good OO.
If you are trying to do C++ things on top of legacy code, sometimes static methods, which are passed pointers to your C++ class can act as wrappers. Heres a simple example of that:
extern int _magicVariable;
static void call( void* klass )
{
((MyClass*)klass)->functionCall( _magicVariable );
}
Inside MyClass, you'll need to name void call( void* ) as a friend. Now the legacy code can call(void*) with a pointer to your class, passing in the _magicVariable into your OO design. From there c++ will do its thing.
The bottom line is you have a lot of ways to accomplish the task, try to do what makes sense based on your desired code structure.
I wanted to make my code more clear - this is why I made an extra cpp file where I declared an array which is taking a lot of space.
But whenever I try to compile my code it says
error c2466: Assignment of an array of constant size can not be
(I translated from German, so don't wonder if you don't know this error 1by1)
The code in main.cpp (To include the file)
#include "mapOne.cpp"
And the code in mapOne.cpp:
int point[100][100][2];
point [1][0][0] = 1; [...]
Can someone help me? I hate it, if a file is >400 lines long just because there is one array declared...
You're trying to assign values to your array outside of a function, which isn't allowed. Instead, the compiler assumes you're trying to declare a new array.
Try wrapping the assignments in a function, and call that function before you start using the array.
The problem you have is happening because you didn't declare the array in an area where your function will be able to use it from. For instance, If I do the following code:
In file1.cpp
int array[20];
In file2.cpp
#include "file1.cpp"
int function1()
{
i = 1;
for (int x = 0; x<20; x++)
{
array[x] = i;
i = i + 2;
}
}
The array[x] would not be recognized. The reason it is not recognized is because even if you use the "include" code on top, you are only including the ability to use the functions that are present in the file1.cpp file. The reason you are only allowed to use the functions and not the variables is simply because the compilers don't want to mix the variables you declare in file1.cpp and file2.cpp. This makes sense because a lot of times you'll declare variables of the same name in different files because it is simpler.
What you can do however is declare the array in a header file. If your writing your function in file2.cpp, you create a header file called file2.h:
In file2.h:
class file2
{
public:
int array[20];///or whichever type of array you want to declare
}
It is important you keep the variables under the "public:" section so that all the functions you make in the file2.cpp can use it.
header.h
int m_linkinfo;
m_linkinfo = 1;
main.cpp
#include "header.h"
int main()
{
return 0;
}
Failed, with many errors. But if I commented the line m_linkinfo = 1;, everything is OK. Why? Cannot I assign values to a variable in header file? But If I changed the header file to the only one line: int m_linkinfo = 1;, The program is compiled successfully! Why? Is it different from the two lines of code above?
No, you can't. That's a piece of code so it needs to exist inside a function of some sort, such as:
int main () {
m_linkinfo = 1;
return 0;
}
You can, as you have seen, initialise it with:
int m_linkinfo = 1;
however, since that's allowed by the standard.
Keep in mind that it's often risky to define things in header files. By define, I mean statements that create things as opposed to those that simply notify the compiler than things exist (declaring).
That's because including the header in two different translation units can result in two copies of a thing with the same name and, if you subsequently try to link them together, you'll run into trouble.
The best way to solve that is to declare things in header files, such as:
extern int m_linkinfo;
and define them in a non-header (eg, CPP) file:
int m_linkinfo = 1;
That way, every translation unit that includes the header knows about m_linkinfo but only the CPP file creates it.
C doesn't allow code outside of functions. In your example:
int m_linkinfo;
m_linkinfo = 1;
The second line is illegal, since it isn't in a function.
Outside of functions you can only declare or define variables and functions (or give directions to the preprocessor).
However, you are allowed to initalise a variable when you define it, so you can do this:
int m_linkinfo = 1;
which is perfectly legal.
Assignment is a statement. Statements are only allowed in functions. The line in the header file is not in a function. Therefore it cannot work.