Variable i cannot be read at compile time - d

I have this code:
class Set(T){
private T[] values;
T get(uint i){
return ((i < values.length) ? T[i] : null);
}
...
And when I try use this class this way:
set.Set!(int) A;
compiler gives error at the return line: set.d|9|error: variable i cannot be read at compile time
Can somebody explain, what's wrong in my code? Thanks.

That is the answer: the code simply referenced the wrong variable. The reason it gave the error it did is that T[i] is trying to get an index out of a compile-time list of types... which needs i to be available at compile time too. However, since i is a regular variable, it isn't. (You can have compile time variables btw - the result of a function may be CT evaled, or the index on a foreach over a static list, or an enum value.) However, what was wanted here was a runtime index into the array... so the values is the right symbol since it is the data instead of the type.
By Adam D. Ruppe

Related

reference to an array of size determined at run-time

I tried to find this but can't find any. I know I can create a reference to an array variable:
int x[10] = {}; int (&y)[10] = x;
However, in the case that the array size is not known at compile time, like in the following code:
const int n = atoi( string ); //the string is read from a text file at run time.
int x[n] = {}; int (&y)[n] = x; //this generates a compiling error.
Even if int n is declared const, as long as n is not known at compile time, the reference is invalid. The compiler will say something like this: reference to type 'int [n]' cannot bind to a value of unrelated type 'int [n]'. Anyone has any idea about how to fix this? Thanks in advance.
Runtime-length arrays are a C99 feature and do not exist in standard C++. They're present as an extension on some C++ compilers, but don't mix well with C++ features, like references and templates.
You should probably use a vector.
The feature of declaring arrays dynamically like shouldn't be used in C++. Not all compilers support it. Consider using the STL containers instead. Like std::vector<int>

Pointers to pointers undefined reference c++ [duplicate]

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;

cast “int32_t” to “static const int32_t”

(Major edit: The way I posed the original question was bit confusing. So, I am trying to improve the question)
I am trying to convert “int32_t” to “static const int32_t” type. However, I could not figure out how to use static_cast and const_cast together. Any help would be appreciated.
I want to do this so that rather than initializing my “static const int32_t IRF_MAX_ENVELOPE_ELEMENTS2” to a hardcore value, I would like to set this based on value passed to the relevant function.
Say, the value of iNoOfSamples_In is 128, I would like to set IRF_MAX_ENVELOPE_ELEMENTS2 to 128 too; but, as as a “static const int32_t” like this:
int32_t iNoOfSamples_In = 128;
static const int32_t IRF_MAX_ENVELOPE_ELEMENTS2 = iNoOfSamples_In;
However, when I go to declare an array of size IRF_MAX_ENVELOPE_ELEMENTS2
double dTime_Scale[IRF_MAX_ENVELOPE_ELEMENTS2]; // Line 80
I get the following errors (line 80 marked in code snippet):
SpecialPulses.cpp(80) : error C2057: expected constant expression
SpecialPulses.cpp(80) : error C2466: cannot allocate an array of constant size 0
SpecialPulses.cpp(80) : error C2133: 'dTime_Scale' : unknown size
So, it seems that max_envelope_elements is not constant.
Just as the error message says, you can't declare a variable as const and then change its value. However, if you are trying to call a function that takes a const int_32, that's fine - just declare the variable as int_32. In that case, the const just says that the function doesn't change the value of the parameter inside the function, but even if it did it wouldn't affect your variable anyway.
By const it means that it's constant and by definition a constant is:
a situation or state of affairs that does not change. - google"
so you cannot change the value of the const variable after you initiated it.
Please do note that const are used most of the time for code readability in replacement for magic numbers in code.
take this for example
if(a>b%2)
//do something
What the heck is 2 and what does that do?
while if you actually can use something like this.
if(a>b%SOME_CONST_VALUE)
//do something
you can actually tell by the const variable what you are actually doing rather than having the programmer/developer who will maintain your code what the heck does that if statement does.
const_cast<int32_t>(IRF_MAX_ENVELOPE_ELEMENTS2)=256;
You can change your constant values like that, I hope this will help your problem.

Using private vars to initialize array

I'm trying to do a little application that would calculate some paths for a given graph.
I've created a class to handle simple graphs, as follows:
class SimpleGraph {
int _nbNodes;
int _nbLines;
protected:
int AdjMatrix[_nbNodes, _nbNodes]; //Error happens here...
int IncMatrix[_nbNodes, _nbLines]; //...and here!
public:
SimpleGraph(int nbNodes, int nbLines) { this->_nbNodes = nbNodes - 1; this->_nbLines = nbLines - 1; };
virtual bool isSimple();
};
At compilation time, I get an error on the two protected members declaration.
I don't understand what is wrong, as there is only one constructor that takes these values as parameters. As such, they cannot be uninitialized.
What am I missing here?
The compiler needs to know how much space to allocate for a member of class SimpleGraph. However, since AdjMatrix and IncMatrix are defined on the stack and their sizes are determined at run-time (i.e., after compilation), it cannot do that. Specifically, the standard says that the size of an array in a class must be a constexpr.
To fix this, you can:
Allocate AdjMatrix and IncMatrix on the heap instead and then you can allocate memory at runtime.
Use a fixed size for the two arrays and keep them on the stack.
--
Another major issue with your code is that you cannot create multi-dimensional arrays using a comma (AdjMatrix[int, int]). You must instead either use:
AdjMatrix[int][int]
AdjMatrix[int * int]
Objects in C++ have a fixed size that needs to be known at compilation time. The size of AdjMatrix and InMatrix are not known at compilation time, only at run time.
In the lines
int AdjMatrix[_nbNodes, _nbNodes]; //Error happens here...
int IncMatrix[_nbNodes, _nbLines]; //...and here!
The array notation is wrong. You cannot specify a 2 dimensional array that way in C++. The correct notation uses brackets on each dimension, as for instance:
int data[5][2];
Regarding the problem you are facing, the dimensions of an array in C++ must be specified at compile time, ie. the compiler must know what are the values used to indicate the array dimension when compiling the program. This is clearly not the case here. You must revert to use integer literals, as in my example, or change the code to use vectors:
std::vector<std::vector<int> > AdjMatrix;
and in the constructor:
SimpleGraph(int nbNodes, int nbLines) : AdjMatrix(nbNodes) {
for (int i = 0; i< nbNodes; i++)
AdjMatrix[i].resize(20);
}
Note that you won't need _nbNodes anymore, and use instead the size() method on AdjMatrix. You will have to do the same for IncMatrix.
Another option, if you know the values at compile time, is to use macros to define them symbolically.
#define NBNODES 20
int AdjMatrix[NBNODES][NBNODES];
but since you wish to pass them as constructor parameter, this may not fit your need. Still, if you know that the parameters are constants at compile time, you might be able use the C++11 constexpr qualifier on the constructor parameters.

warning: uninitialized variable //But I have initialized ! C++ Compiler bug?

Iam trying to compile this program but i get warning and when i run vc++ 2010 debugger pops up : (
Here is my code :
#include <iostream>
using namespace std;
int num;
int min(int mas[])
{
int i,minn,index; /* But I have declared them : (((( */
for(i=0;i<num;i++)
{
if(mas[i]!=0)minn=mas[i];
break;
}
if(i==num) return 0;
for(i=0;i<num;i++)
if(mas[i]!=0 && minn>mas[i])
{
minn=mas[i];
index=i;
}
mas[index]=0;
return minn;
}
int main()
{
cin>>num;
int *array=new int[num]; int tmp;
tmp=min(array);
}
and Here is a compiler log :
prog.cpp: In function ‘int min(int*)’:
prog.cpp:6: warning: ‘index’ may be used uninitialized in this function
prog.cpp:6: warning: ‘minn’ may be used uninitialized in this function
What i am doing wrong ? or its is compiler bug ? :)
Thank you :)
You have declared them, but not initialized them. Simply write int minn = 0, index = 0; to avoid the warning. If you don't initialize a variable, its default value is whatever was at that location in memory already; usually garbage.
The thing is, if num is negative, then neither of the for loops in your min() function will execute, and so minn and index will not have been assigned values. The if(i == num) test also won't break out of the function and prevent this from happening. So the last two lines of the function will have completely undefined results.
Sometimes there really isn't a path for the variables to be used uninitialized, though; sometimes the compiler just isn't quite smart enough to figure out all the subtleties. Just give them an initial value to avoid the warning.
Declaration != initialization. When you declare them the variables have random values. Just initialize them to sensible values like -1 for index and minn to a INT_MAX.
But you haven't initialized them : ))))
EX: int i,minn=0,index=0; Imagine that you pass num that equals 0, at the end you would be returning uninitialized value of minn and just before that you would set mas[unknown_number]=0; which will probably cause your app to crash since you will be referencing memory that is most likely beyond your scope. You should do a check in the beggining like if(num<1)return -1;
Suppose the entire array you pass in is 0. Both loops short-circuit and never execute, both minn and index are uninitialized.
Now if this happens, what should be happening? Set the variables to the values that accomplish just that.
As you say in your comment, yes, you have declared your variables, but you haven't initialized them. Initializing a variable means giving it a value. So in this case, you have told the compiler that you want to create three integers, but you haven't told it what values you want to store in those integers. That would be ok if, for every possible path through your function, index and minn were guaranteed to be given a value, but the problem here is that there is a path through your function where minn and index will never be initialized. First of all, here:
for(i=0;i<num;i++)
{
if(mas[i]!=0)minn=mas[i];
break;
}
If you have an array of zeros, then minn is never initialized to a value.
Then further down:
for(i=0;i<num;i++)
if(mas[i]!=0 && minn>mas[i])
{
minn=mas[i];
index=i;
}
first of all, if you had an array of zeros, well what is the value in minn? There is no value. You are asking the compiler to compare mas[i] to a number which doesn't exist. Furthermore, what if mas[i] is always equal to zero? Well now you don't initialize minn or index. Yet at the end of the function, you are attempting to use the value of index to get an integer from the array amd then you return minn (which still equals nothing).
That's the problem you're getting from the compiler. It can see this potential outcome and is warning you that your function can be broken due to these integers never getting a value. To fix it, do what the other lads have suggested and let index and minn equal zero at the start.