Minh Nhat
Minh Nhat

Reputation: 11

I'm having an 2D Array Redefinition Error

There is an error (actually 3 same errors) with my definition array int mang[max][max] and I couldn't find anything to fix it properly, so I hope someone will notice my question and help me soon. XD

In my header file array.h, I have:

#include <iostream>
#define max 100
using namespace std;
int mang[max][max];

void NhapMang(int mang[][max], int hang, int cot); 
void XuatMang(int mang[][max], int hang, int cot);
int TinhTongPhanTu(int mang[][max], int hang, int cot);
int DemPhanTux(int mang[][max], int hang, int cot);

When I was typing my code, VS shows me that there is "no issues found" all over .cpp files, but when I debug the code, the error appears in the header file array.h, says "C2086 'int mang[100][100]': redefinition" altogether. I think that I've defined mang twice or more, but I couldn't find the other mang definition nor fixing it if I found. This is the capture of the error list. I don't know what parts I need provide to you in my project to help fixing it for me (and I also think my post would become so long to read if I copy-paste all my code up here :-( ), so if you need any further information, just comment and I will give it to you.

And well, I've just start learning C++ for 3 months, so there's soooo many things I haven't known yet XD If there's anything I couldn't understand in the way you fix the problem, please let me ask you more about it.

Hope you understand what I mean XD (cuz I'm not a native speaker). And thank you for reading.

Upvotes: 1

Views: 911

Answers (2)

The key here is that the pre-processor is a text altering engine. In every file where you have #include "array.h", the textual contents of array.h are inserted in place of the #include.

So, if you have several files that include array.h then each one of those files declares and defines mang (all using the same definition). That isn't a problem during compilation because each file is compiled separately, but they each generate an object file that defines mang.

Then you try to link, and the linker sees several defitions of the array.

The solution is the same as the one you are using for functions in array.h: you declare in the header and define in the implementation (presumably array.cpp).

How do you declare an array without defining it?

Good question. I'm glad you asked. You do it with the extern keyword like this.

array.h:

// ...
#define max 100
extern int mang[max][max];      // <=== Look here (with extern)
// ...

Then you define it in array.cpp:

// ...
int mang[max][max];      // <== and compare to this (no extern)
// ..

As an aside you using the pre-processor to define constants (like #define max 100 has several downsides, and in c++ you are generally better off using compile-time constants like

const int max = 100;  // Pre c++11

or

constexpr int max = 100; // c++11 or later

(The use of the pre-processor for this is a holdover from ancient days when compilers were a lot less clever.)

Upvotes: 3

eerorika
eerorika

Reputation: 238311

The language rules say:

[basic.def.odr]

Every program shall contain exactly one definition of every non-inline function or variable that is odr-used in that program outside of a discarded statement; no diagnostic required. ...

(There are some exceptions with limitations that are listed in further rules, but none that apply to your example)


int mang[max][max];

This is definition of a variable. That definition is in a header file. Header files are typically included into multiple translation units. If you do so, then you have included the definition of the variable into multiple translation units. By having multiple definitions of a non-inline variable, you would violate the rule quoted above.

Upvotes: 2

Related Questions