(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.
Related
This question already has an answer here:
Array[n] vs Array[10] - Initializing array with variable vs numeric literal
(1 answer)
Closed 12 months ago.
What i would like to do is declare an array with "dim" size :int A[dim];.
Now, this works if I declare something like const int dim = 1 but doesn't with const int dim = round(x);, which is what i need to do. (Where x comes from cin >> x.)
Note: With "doesn't work" i refer to Visual Studio Code throwing red wavy line under dim in int A[dim]; and displaying the following when hovering it with my mouse:
`
expression must have a constant valueC/C++(28)
main.cpp(15, 11): the value of variable "dim" (declared at line 13) cannot be used as a constant
`
This is the relevant code:
#include <iostream>
using namespace std;
int main(){
float x;
cin >> x;
const int dim = round(x);
int A[dim];
int i = 0;
}
}
Given the context i believe the error is caused by one of two reasons:
Some characteristic of round() that makes the const int dim = round(x) not recognized as constant from the array later.
The problem is the x and not the round() so cin >> x is the reason.
[Thanks for whoever can explain me what I'm missing or point to some documentation that does. I have done some research but I haven't found a solution to this. Also this is my first question on SO, so tell me if I should change/improve something]
EDIT: Apparently the problem isn't in the round(x) as I previously thought because simply replacing const int dim = round(x); with const int dim = x; gives the same "error".
So the problem has to do with cin >> x .
EDIT 2 Note: I'm looking for a solution that doesn't use std::vector. We haven't studied it yet in the course so I believe the algorithm(from which i took the relevant code) shouldn't comprehend it.
Final Edit I didn't realize that, as #paulmckenzie clarified, using cin made the array dynamic because the imput comes in runtime, it was a really stupid error but I apologize, I'm really a beginner. In my defense we really haven't talked about dynamic size arrays so I guess that's what threw me off. I realized from the beginning I was missing something very basic, sorry for wasting time, I'll put even more time analyzing everything before posting next time.
The size of an array variable must be compile time constant in C++. User input is not compile time constant, hence it cannot be used as the size of an array variable.
In order to create an array with runtime size, you must instead create a dynamic array. The simplest way to do that is to use std::vector from the standard library.
EDIT 2 Note: I'm looking for a solution that doesn't use std::vector.
It's possible to create a dynamic array without std::vector, but that requires the use and understanding of more advanced concepts. Using new expressions directly is more difficult, error prone and is something that isn't (or shouldn't) be done in most programs in practice.
Of course, another solution is to just not use user input but rather an array with constant size.
I am getting the following error from PVS Studio
V669 The 'fetch_mask' argument is a non-constant reference. The analyzer is unable to determine the position at which this argument is being modified. It is possible that the function contains an error.
This is the line:
XXH64_state_t* hash_state, uint32_t& fetch_mask
I was figuring the error was the & isn't part of fetch_mask I fixed it like:
XXH64_state_t* hash_state, uint32_t &fetch_mask
The error goes away. However, travis.cl test says I need to reformat and fails.
I think found problem original codes.
void TextureCache::HashTextureBindings(
XXH64_state_t* hash_state, uint32_t& fetch_mask,
const std::vector<Shader::TextureBinding>& bindings) {
for (auto& binding : bindings) {
uint32_t fetch_bit = 1 << binding.fetch_constant;
if (fetch_mask & fetch_bit) {
void HashTextureBindings(XXH64_state_t* hash_state, uint32_t& fetch_mask,
const std::vector<Shader::TextureBinding>& bindings);
I removed the & since I think it is supposed to be uint32_t fetch_mask instead of uint32_t& fetch_mask
As I understand we are talking about this code. I’ll write the whole body of a function:
void TextureCache::HashTextureBindings(
XXH64_state_t* hash_state, uint32_t& fetch_mask,
const std::vector<Shader::TextureBinding>& bindings) {
for (auto& binding : bindings) {
uint32_t fetch_bit = 1 << binding.fetch_constant;
if (fetch_mask & fetch_bit) {
// We've covered this binding.
continue;
}
auto& regs = *register_file_;
int r = XE_GPU_REG_SHADER_CONSTANT_FETCH_00_0 + binding.fetch_constant * 6;
auto group =
reinterpret_cast<const xenos::xe_gpu_fetch_group_t*>(®s.values[r]);
auto& fetch = group->texture_fetch;
XXH64_update(hash_state, &fetch, sizeof(fetch));
}
}
As you can see, the variable fetch_mask is used only for reading in the expression if (fetch_mask & fetch_bit). It is strange to pass an integer variable by reference and not to modify it. This is often a sign that the code contains an error. Yes, it's not always a mistake, but this code should be carefully verified.
For PVS-Studio analyzer it does not matter, if uint32_t& fetch_mask or uint32_t &fetch_mask is written. In any case, it will issue the warning .
Probably, there is no error here. You can eliminate the warning by removing the link & as you did. Another option is to use one of the mechanisms of suppression of false positives.
The error indicates, that you are passing a non-const reference to a variable into a function, but PVS-Studio is unable to see, whether that variable actually gets modified. The purpose of passing an argument by reference is, that a function can modify the original value. If a function doesn't modify a value passed by reference, that reference should be const instead (i.e. uint32_t const& fetch_mask).
Passing a variable by value is another way to express, that a function doesn't modify the original value (although I prefer to pass by const value as well, so that it doesn't get accidentally assigned). For integral data types it is common to pass them by (const) value.
The diagnostic is essentially questioning, whether the intended purpose and code match up. The purpose of the code is, that the variable passed through the fetch_mask formal parameter can be modified, yet the implementation doesn't attempt to do so (unless it's doing so in a way that PVS-Studio cannot see, e.g. by aliasing it).
For reference, here is the official documentation for V669:
The analyzer has detected that an argument is being passed by reference into a function but not modified inside the function body. This may indicate an error which is caused, for example, by a misprint.
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
I've come across some interesting findings relating to runtime detection that has spurred an interesting question. If I want to declare a global variable based off a condition, I can easily do so during pre-compilation with #ifdefs. However, this produces different binaries, and I am looking for a solution that can be realized during runtime so as to constrain behavior to a single binary.
Example
A classic example that I can perform with arrays or other data types (note, the data types here are all const and must remain so - mirroring the immutable behavior of an enum):
Original (Compile Time):
#ifdef CONDITION
static const int faveNums[] = {......};
#else
static const int faveNums[] = {******};
#endif
Modified (Run Time):
static const int conditonalFaveNums[] = {......};
static const int defaultFaveNums[] = {******};
static const int * const faveNums = IsConditionTrue() ? conditonalFaveNums : defaultFaveNums;
Common Pitfall (Scoping):
This is a common pitfall that will not work, as if/switch conditionals are scoped and therefore unable to be referenced later - thank goodness for the ternary operator!
if(IsConditionTrue())
{
static const int faveNums[] = {......};
}
else
{
static const int faveNums[] = {******};
}
Problem
However, the situation appears to change with enums. Let's try the run time solution, but with an enum this time:
enum conditionalFaveNums = {......};
enum defaultFaveNums = {******};
enum faveNums = IsConditionTrue() ? conditonalFaveNums : defaultFaveNums;
This will not compile.
Compile time defines (as with the first example) can solve this, but is there a way to solve this at run time by conditionally declaring a global enum in C++?
While you can't do exactly what you're asking - the difference between your array and enum examples being that the array is simply data, whereas the enum is a type, and type definitions must be resolvable at compile time - perhaps a more helpful answer is that this is a good thing.
Dynamic data should be represented in a dynamic data structure. std::set is a pretty close conceptual match to an enum, and provides many useful (and efficient) methods that may come in handy later. Even better might be defining an enum listing all possible values at compile time, and then dynamically constructing a set of these values based on runtime information. (The set is thus a proper subset of the enum's range.)
You cannot do this. Key points to remember:
Values of variables can be initialized differently based on run time information.
Types MUST be defined/set at compile time.
You can use
static const int * const faveNums = IsConditionTrue() ? conditonalFaveNums : defaultFaveNums;
since that says what faveNums is to be initialized to at run time, using run time information.
You cannot use
enum faveNums = IsConditionTrue() ? conditonalFaveNums : defaultFaveNums;
since that tries to define the type faveNums using run time information.
I'm building a comparator for an assignment, and I'm pulling my hair out because this seems to simple, but I can't figure it out.
This function is giving me trouble:
int compare(Word *a, Word *b)
{
string *aTerm = a->getString();
string *bTerm = b->getString();
return aTerm->compare(bTerm);
}
Word::getString returns a string*
Error:
In member function `virtual int CompWordByAlpha::compare(Word*, Word*)':
no matching function for call to...
...followed by a bunch of function definitions.
Any help?
You're comparing a string to a string pointer, and that's not valid. You want
return aTerm->compare(*bTerm);
You aren't getting the different uses of the * operator. The use of the * in "string* bTerm = b->getString()" means "bTerm is a pointer to a string". The use of the * inside of compare(*bTerm) means "take the value of the location pointed to by bTerm" instead of just using compare(bTerm) which simply attempts to compare the value of bTerm itself, which is a hex address.
This is also happening on the left side of that call:
aTerm->compare(*bTerm); //this statement
(*aTerm).compare(*bTerm); //is the same as this statement
The -> operator just reduces the amount of typing required.
P.S.: This kind of stuff you could have easily figured out from Google or your programming textbook. Although others may disagree, I don't feel that questions about completely basic syntax have any place on Stack Overflow.