Global multidimensional array not being written to [vs c++] - c++

I have a global multidimensional array, g_iAllData[MAX_LEN][MAX_WIDTH] being used in a Form. When I write to it in a function: g_iAllData[iRow][iColumn]= iByte_Count; I can see in a Watch Window that it's contents are not being changed. If I put the array in the function, it works fine.
Is there something I'm missing? I am declaring it as global after my #include's at the top of the Form1.h file. I have multiple functions that are called by buttons being pressed and I need to write and read from the array in each function. It would be easier to keep it as global instead of passing it to each function.
UPDATE code:
ProgramName.cpp
#include "stdafx.h"
#include "Form1.h"
Form1.h
#include <iostream>
#include <string>
...
#pragma once
const int MAX_LEN = 4033;
const int MAX_WIDTH = 21;
int g_iAllData[MAX_LEN][MAX_WIDTH];
...
namespace ProgramName{
// later on
ReadFile();
void ReadFile(void)
g_iAllData[iRow][iColumn]= iByte_Count;

Your code sample really confirms that you have a problem with your variable declaration.
As #Graham hinted, the proper way to define globals is:
define the variable in a cpp file
declare the variable as extern in a header file
I.e.
//ProgramName.cpp
#include "stdafx.h"
#include "Form1.h"
int g_iAllData[MAX_LEN][MAX_WIDTH];
//Form1.h
#include <iostream>
#include <string>
...
#pragma once
const int MAX_LEN = 4033;
const int MAX_WIDTH = 21;
extern int g_iAllData[MAX_LEN][MAX_WIDTH];
This way the linker will find the definition of the global variable in exactly one compilation unit, and in all other compilation units which #include the header, it will be able to link the extern declarations to the correct variable definition.
Barring this, strange things may happen: you may get cryptic linker error messages complaining about multiple variable definitions, or you might even get multiple distinct variables in your app instead of one global variable - the latter explains why your method doesn't seem to change the contents of your variable.

Are you including Form1.h in other files too? If so, you need to use 'extern' in the other files.

If you defined your array in header file (as you code shows), then every time you include that header in a translation unit, you effectively define a separate "copy" of your array. This is not even supposed to compile, since you are defining multiple instances of the same external object (violation of ODR).
If you managed to compile it somehow (how?), then there's no way to say which instance of g_iAllData you are modifying and which instance the debugger shows you in the watch window. Could be different instances, which is why you don't see the change.
Objects with external linkage should not be defined in header files. You better reconsider your approach.

Related

Which of these two is the proper way to implement a header?

Should you include #include the header of your function declaration in the source file where you define the function?
I've tried both and it seems to work either way. I was wondering if either way is preferred or if one might cause an error in a different compiler
//header.h
#ifndef HEADER_H
#define HEADER_H
int squareVal (int);
#endif
//squareVal.cpp
//should I #include "header.h" here as well?
int squareVal (int val){
return (val*val);
}
//main.cpp
#include"header.h"
using namespace std;
int main(){
cout << squareVal(2) << endl;
}
Both ways seem to work. From my testing and research it sounds like the linker is able to find squareVal.cpp regardless of including the header in that file or not.
Use the #include directive. Put it at the top, in front of any other #include directives. That way, if there's a mistake in the header, the compiler will be more likely to find it. In particular, if you declare the function differently from the way you define it, the compiler will notice. If you don't pull in the header, translation units that use that header will see a different signature from the one that's been defined, and you'll get errors when you try to link. It's much easier when you see the problem early.
Whether it makes a difference, depends on the contents of the header.
In this specific case, because a function definition does not require a previous function declaration, the #include in squareVal.cpp is not (and never will be) necessary.
However, imagine if the header contained more than the function declaration? What if it defined some types needed by the function? What if it defined some constants needed by the function definition? Then you'd need an #include.
It is considered good practice to #include regardless, because then you do not need to think about this, and doing so is effectively free.
The compiler simply puts the WHOLE code from the header right where you insert the #include "header.h". So in this example, the declaration is before the definition of the function and it does nothing bad.

Confused about 'extern' and 'static extern' storage classes in C++11

I read over a few articles about this, and am taking a few introductory courses to C++ concurrently. All of the courses I am taking and these articles just don't help me understand how to implement the extern and static extern storage class. I don't feel comfortable moving on until I really have a grasp on this, even though what I am seeing from other programmers is that they do not use these storage classes, but use inheritance from a header file and local static storage class to use a static variable in a function. Both of those instances I can do. I figured out how to use the static storage class both within the same source file and also by inheriting the static variable from an inherited source file.
I keep getting linker and / or compiler errors.
I am using Visual Studio 2015 Community Edition with C++11, and have CodeDroid in Android with C++98.
Will someone please teach me how to use the extern and static extern storage classes without linker and compiler errors?
For example, say I had one.cpp and two.cpp. Say I have an int main() function in one.cpp. Say I want to demonstrate outputting the value of an extern int in the main() function. And, say I have a void function called extFuncExample() declared and defined in one.cpp, and also want to output its value there.
A course I am taking has extern and static extern as two different storage classes. So, if you would be so kind as to break this down to me, so I can output these values without compiler and linker errors.
Thank you so much!
one.cpp
#include <iostream>
#include "Two.cpp"
int main()
{
extern int global_int;
std::cout << "global_int = " << global_int << '\n';
return 0;
}
two.cpp
#include <iostream>
int global_int = 100;
This, I found works. I was including #include "two.cpp" in one.cpp and also using the extern storage class which was causing the issues. Removed #include "two.cpp" and it worked!
In C and C++ there is a difference between a (forwards) declaration and a definition of symbols. extern is used to forwards declare the existence of a symbol which is external to the translation unit, that is: to 'import' symbol from "somewhere" and "make it visible" to the code being compiled. At link time the references to external symbols are resolved.
Effectively extern is a way to instruct the compiler/toolchain that it should not expect to find the symbol definition among the code being compiled, but instead should look in the libraries being linked against to find it. The linker will not bother to do so for symbols that aren't declared extern.
Apart from that, there is a somewhat common mistake that people make with extern: to use it to declare a global variable and also define it inside a header. For example:
// some header.h
extern int my_global = 40; // = 40 makes this wrong.
Then they proceed to include it multiple times in different translation units (source files):
// file1.c{pp}
#include "header.h"
// file2.c{pp}
#include "header.h"
At this point you have introduced multiple definitions for the same symbol in your program because #include simply copies the contents of the header verbatim into the context at which the #include is performed. The compiler will still compile the code, but the linker will refuse to link it because of the multiple definition error.

Access extern variable in C++ from another file

I have a global variable in one of the cpp files, where I am assigning a value to it. Now in order to be able to use it in another cpp file, I am declaring it as extern and this file has multiple functions that use it so I am doing this globally. Now the value of this variable can be accessed in one of the functions and not in the other one. Any suggestions except using it in a header file would be good because I wasted 4 days playing with that.
Sorry, I'm ignoring the request for answers suggesting anything other than the use of header files. This is what headers are for, when you use them correctly... Read carefully:
global.h
#ifndef MY_GLOBALS_H
#define MY_GLOBALS_H
// This is a declaration of your variable, which tells the linker this value
// is found elsewhere. Anyone who wishes to use it must include global.h,
// either directly or indirectly.
extern int myglobalint;
#endif
global.cpp
#include "global.h"
// This is the definition of your variable. It can only happen in one place.
// You must include global.h so that the compiler matches it to the correct
// one, and doesn't implicitly convert it to static.
int myglobalint = 0;
user.cpp
// Anyone who uses the global value must include the appropriate header.
#include "global.h"
void SomeFunction()
{
// Now you can access the variable.
int temp = myglobalint;
}
Now, when you compile and link your project, you must:
Compile each source (.cpp) file into an object file;
Link all object files to create your executable / library / whatever.
Using the syntax I have given above, you should have neither compile nor link errors.

Classes interfering with each other on compile

I'm working on a C++ project.
I had a class with its function, then I realized some of those functions weren't related to that class but were just math functions so I decided to move them on to a namespace.
My first question is, what is the appropriate file extension for a c++ namespace?
I have a constants.h file where I plan on saving global constants, for example PI.
Right now:
#include <math.h>
const double PI = M_PI;
I have the namespace I talked about before, right now is called: specificMath.h
#include <stdlib.h>
#include "constants.h"
... more code
I have a gaussian.cpp:
#include "gaussian.h"
#include "specificMath.h"
#include <iostream>
... more code
This file includes a main function that right now does nothing, I just can't get the whole project to compile without a main...
I have a gaussian.h where I'm not including anything, is that wrong?
A third class, which has no attributes, just methods (again, is this wrong? or not pretty?). truncatedFunctions.cpp
#include "specificMath.h"
#include <stdlib.h>
#include "truncatedFunctions.h"
#include "gaussian.h"
using namespace specificMath;
And its truncatedFunctions.h where, again, I'm not including anything.
And a fourth class where I include
#include "margin.h" //Its header, where I'm not including anything
#include "gaussian.h"
#include "specificMath.h"
using namespace specificMath;
When I "make" it, it seems to compile fine, but when it gets to the linking part I get A LOT of errors saying that things on my margin.cpp class were first defined in truncatedFunctions.cpp
I am going crazy. I have no idea why this is happening, or how to solve it. I would really appreciate if somebody could help me out, and please, any extra piece of advice would be great since I am really trying to learn as much as I can with this project. Thanks!
When I "make" it, it seems to compile fine, but when it gets to the linking part I get A LOT of errors saying that things on my margin.cpp class were first defined in truncatedFunctions.cpp
Did you define your functions in your specificMath.h? You should only declare those functions.
For example, if your specificMath.h contains function definitions like
#ifndef COOL_STUFF_NSPC
#define COOL_STUFF_NSPC
#include <iostream>
namespace coolstuff{
void print(void){std::cout << "I'm declared in a header file." << std::endl;
}
#endif
and you are using including this file in several others, the linker is going crazy. Including means copying. And so you've got yourself coolstuff::print defined several times. The better way (and the only possible way when using self-written functions in many files) is splitting your code into a header and implementation as you did in gaussian.
// coolstuff.namepace.h
#ifndef COOL_STUFF_NSPC
#define COOL_STUFF_NSPC
namespace coolstuff{
void print(void);
}
#endif
When you include coolstuff.namespace.h it will only declare functions. And you can declare the same function several times.
// coolstuff.namespace.cpp
#include <iostream>
#include "cs.h"
void coolstuff::print(void){
std::cout << "Hello world!" << std::endl;
}
The .cpp file contains the implementation of your functions. Now your linker won't get irritated because there is only one implementation of coolstuff::print and not n (where n is the number of #include "cs.namespace.h" you used) ones.
My first question is, what is the appropriate file extension for a c++ namespace?
There is no standard namespace extension. Use .h/.cpp for header/implementation and a self-defined prefix, something like 'nmspc' or 'nsc'. It's up to you.
It's hard to tell whether you've done anything wrong in your code (because you didn't show any of it), but the first thing to try is to "clean" your build and rebuild all your code. If the compiler (don't know what you're using) for some reason didn't compile all your modified modules, then it's not surprising that the linker is having trouble.
My first question is, what is the appropriate file extension for a c++ namespace?
In C++, header files are usually .h or .hpp. It doesn't matter to the compiler.
#include "gaussian.h"
#include "specificMath.h"
#include <iostream>
In general, it's a good idea to #include stuff from the standard library first, followed by your own things.
I have a gaussian.h where I'm not including anything, is that wrong?
No. If you don't need to include anything, don't include anything.
First, use include guards for the headers.
#ifndef MYHEADER_H
#define MYHEADER_H
//header contents
#endif
This will prevent the same header from being included twice in the same translation unit.
Second, don't define uncosnt stuff in the headers:
double x = 0;
this will cause all translation units to export that symbol.
Declare the variable extern in your header and provide a definition for it in an implementation file.

How can I avoid the LNK2005 linker error for variables defined in a header file?

I have 3 cpp files that look like this
#include "Variables.h"
void AppMain() {
//Stuff...
}
They all use the same variables inside them so they have the same headers but I get stuff like this
1>OnTimer.obj : error LNK2005: "int slider" (?slider##3HA) already defined in AppMain.obj
Why is that?
Keep in mind that a #include is roughly like cutting and pasting the included file inside the source file that includes it (this is a rough analogy, but you get the point). That means if you have:
int x; // or "slider" or whatever vars are conflicting
in the header file and that header file is included by three source files in a program, then they will all have a global named x defined that will conflict.
What you want to do is define the variable as extern so that the .cpp files will all get the declaration, and then in ONE of your .cpp files give the actual definition.
in Variables.h:
extern int x;
in SomeSourceFile.cpp
int x;
Of course, I'd recommend against globals, but if you must use them this would keep them from conflicting.
This is because the compiler compiles each .cpp file separately, creating a .obj file for each one. Your header appears to have something like:
int slider;
When this is included into each of your three .cpp file, you get three copies of the int slider variable, just as if you had declared it in each .cpp file. The linker complains about this because you haven't have three different things with the same name.
What you probably want to do is change your header file to read:
extern int slider;
This tells the compiler that there is a slider variable somewhere, but possibly not here, and lets the linker figure it out. Then, in one .cpp file:
int slider;
gives the linker one actual variable to link.
Because "int slider" is already defined in another file? Check that you have header guards...
#ifndef _VARIABLES_H_
#define _VARIABLES_H_
int slider;
#endif
If it is across multiple translation units, and you do want the variables to be different (ie not global), then maybe declare them in an anonymous namespace:
namespace {
int slider;
}
If you do want them global, look to James' solution.
What is happening is that each of the variables from Variables.h are given global scope for each of the individual c files. When the linker compiles all the c files, it sees multiple variables with the same name.
If you are wanting to use variables from the header file as global variables, then you will have to use the keyword "extern" in front of all of them, and in the main file don't use the keyword extern.
main c:
int n_MyVar;
other files:
extern int n_MyVar;
You can create two files Variables.h and EVariables.h, or just declare the variables in the main.cpp file.
A much better way to do this is to create a class of Variables and pass a reference to the class.
I know that this is an old thread, but I came across this as one of the first search results from Google. I solved the problem by placing the variable static.
namespace Vert
{
static int i;
}
I tried extern and in my situation that didn't seem to solve the problem.
This linking error can also be avoided if the variables included multiple times via the "Variables.h" are declared as const.
I had this error too although I work with extern definitions. The problem was initializing the variables in the extern definitions too:
ID3D11VertexShader* g_pVertexShader = nullptr;
...
extern ID3D11VertexShader* g_pVertexShader = nullptr; // here's the problem
=> error
ID3D11VertexShader* g_pVertexShader = nullptr;
...
extern ID3D11VertexShader* g_pVertexShader; // without initializing
=> no error, problem solved