replacement of magical number crashes the program

Hi,

I am trying in this code example to replace the magical number "52" with a const int. When I do this the program stops compiling. What is wrong here/what am I missing to successfully substitute the magic number?

code that works:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include<iostream>
#include<array>

using namespace std;


struct Card_Objects
{
	int suit;
	int rank;
	int index;
};


void fill_array(array<Card_Objects, 52> &card_deck)
{
	cout<<"stuff";

}


int main()
{
	const int max_rank = 52;
	const int max_suit = 4;
	array<Card_Objects, 52>card_deck;
	fill_array(card_deck);

	return 0;
}

After assigning the magical number to a const var:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include<iostream>
#include<array>

using namespace std;


struct Card_Objects
{
	int suit;
	int rank;
	int index;
};


void fill_array(array<Card_Objects, max_rank> &card_deck)
{
	cout<<"stuff";

}


int main()
{
	const int max_rank = 52;
	const int max_suit = 4;
	array<Card_Objects, max_rank>card_deck;
	fill_array(card_deck);

	return 0;
}


--doesn't work.

compiler errors:

++ -std=c++0x -std=c++11 -O0 -g3 -Wall -c -fmessage-length=0 -o "src\\main.o" "..\\src\\main.cpp"
..\src\main.cpp:15:37: error: 'max_rank' was not declared in this scope
void fill_array(array<Card_Objects, max_rank> &card_deck)
^
..\src\main.cpp:15:45: error: template argument 2 is invalid
void fill_array(array<Card_Objects, max_rank> &card_deck)
^
..\src\main.cpp: In function 'int main()':
..\src\main.cpp:27:22: error: invalid initialization of reference of type 'int&' from expression of type 'std::array<Card_Objects, 52ull>'
fill_array(card_deck);
Last edited on
Hi,

void fill_array(array<Card_Objects, max_rank> &card_deck)
Passing an std::array like this, with a variable of an unknown size rather than a magic number doesn't work. If you want to do it this way, you'll have to use a template, take a look here -

http://stackoverflow.com/questions/17156282/passing-a-stdarray-of-unknown-size-to-a-function


Full program using template:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include<iostream>
#include<array>

using namespace std;


struct Card_Objects
{
	int suit;
	int rank;
	int index;
};

template<int max_rank>
void fill_array(array<Card_Objects, max_rank> &card_deck)
{
	cout<<"stuff";

}


int main()
{
	const int max_rank = 52;
	const int max_suit = 4;
	array<Card_Objects, max_rank>card_deck;
	fill_array(card_deck);

	return 0;
}
Last edited on
Thx for that article. Its very specific.
Hi,

Just a note about the types being used: Prefer std::size_t rather than int here. For a couple of reasons:

1. You don't want negative values here;
2. I like to use exactly the same type as what a function or template expects: to avoid any unnecessary implicit casting. This is the definition from cppreference:

1
2
3
4
5
template<

    class T,
    std::size_t N
> struct array;


Btw, I managed to get the OP's code to work, but I had to resort to making max_rank global, and have it before any mention of the std::array. So this is clearly a bad solution, the use of the template is a much better idea.

I suppose the next question is: why the compiler has trouble with this ? It seems that the value is not "unknown", it was defined in main. My guess is that the compiler generates an instance of the template the first time it sees it*, in this case whether that be for a function definition in the OP's code, or a forward declaration of the function. At this time the variable is unknown: it's scope is main. Making it static or constexpr in main doesn't help: the scope is still main.

* I know templates are instantiated only when they are needed, but here we have a function that uses one, so it is needed.
Yes, it is interesting how the compiler reacts to it. Its a known var if it just "looks" a little farther. I can see why you made max_rank global. I am learning about std::arrays and this just hit a vulnerability. The templates seem like the answer but I haven't gone over them yet to any great extent mostly because they are to be convered.
Topic archived. No new replies allowed.