0

I was making a simple program related to arrays. My Code:

#include <iostream> #include <cmath> using namespace std; int main() { int a; cout << "Please enter the length of the array: " << endl; cin >> a; bool array[a]; for (int n = 0; n < a; n++) { array[n] = true; } array[0] = false; array[1] = false; for (int k = 2; k < a; k++) { if (array[k] == true){ for (int i = 0; pow(k,2)+ i*k < a; i++) { array[ pow(k,2) + i * k] = false; } } } for (int j = 0 ; j < a ; j++){ if (array[j] == true){ cout << j <<endl; } } 

}

I get an error in the line

array[ pow(k,2) + i * k] = false; 

It says

"Invalid Types" ||=== Build: Debug in Test (compiler: GNU GCC Compiler) ===| C:\Users\Momo\Documents\CodeBlocks Projects\Test\main.cpp||In function 'int main()':| C:\Users\Momo\Documents\CodeBlocks Projects\Test\main.cpp|21|error: invalid types 'bool [(((sizetype)(((ssizetype)a) + -1)) + 1)][__gnu_cxx::__promote_2<int, int, double, double>::__type {aka double}]' for array subscript| ||=== Build failed: 1 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===| 

That is the error. I am trying to switch from Java to C++. However such kind of error is new to me as I never encountered such error in Java. Can you guys and girls help me understand what this means? And what can I do to resolve it? Thanks.

5
  • bool array[a]; This is not legal ANSI C++. Array sizes in C++ must be declared using a compile-time expression, not at runtime. You're using a compiler extension. Commented Feb 6, 2016 at 7:36
  • I am trying to switch from java to c++. However such kind of error is new to me as i never encountered such error in java -- C++ is not Java. Pretend Java doesn't exist, otherwise you'll wind up developing C++ that attempts to look like Java. Commented Feb 6, 2016 at 7:38
  • Okay i'll try my best to forget it . But how should i take the size of the array from the user and then use it to create the suitable array? Commented Feb 6, 2016 at 7:44
  • Note that using floating point index, even in Java, will get you in trouble w.r.t. floating point inaccuracies. See my answer below. Commented Feb 6, 2016 at 8:18
  • "However such kind of error is new to me as I never encountered such error in Java." - This is exactly the same error as the one you'd get in Java when you try to use the result of Math.pow as an array index. Commented Feb 6, 2016 at 9:32

4 Answers 4

2

Using man pow ,you can get the following:

 double pow(double x, double y); 

From that we know pow() return double.But array subscript must be an size_t variable.So you can change that line into:

array[ static_cast<size_t>(pow(k,2)) + i * k] = false; 
Sign up to request clarification or add additional context in comments.

Comments

2

First, this:

bool array[a]; 

is not legal C++. What you're probably using is a compiler that supports Variable Length Arrays. But again, VLA's are not standard C++. In its place you can use:

#include <vector> //... std::vector<bool> a(n); 

But this also has issues, however for your purposes it shouldn't be a problem.


Now for this:

array[ pow(k,2) + i * k] = false;

the error is as stated. In C++, you cannot use double as an index type. The pow function returns a double, thus that expression in total becomes double.

You can only use an integral type for an array index. If you truly want to use a double as a type, either:

  1. Create your own class and overload operator [] to take a double, or
  2. Less desirable (see cautionary note below), you can use a std::map<double, bool>. It isn't the same as an array, but the syntax of using a double and operator[ ] will look "array-like".

For the second option:

 #include <map> //... std::map<double, bool> array; 

Then you can use syntax such as array[pow(k,2]] = false;. However be cautious in using [ ], since for a map, operator [ ] will create a new key / data entry if the value specified in [ ] doesn't exist. So you risk creating "holes" in your ersatz array.


But given all this, there is a fundamental flaw in using floating point values as array (or even std::map) indices (or keys w.r.t a map). The flaw is that floating point calculations are inexact -- a differing compiler, compiler setting, etc. could yield different results when you run your program. The index may be one-off if you, for example, compile with one set of options, and then rebuild with another set of options.

Also, if you say that "how can pow(k,2) be faulty if k is an integer?" Well this link will show that you cannot be sure.

10 Comments

Why does std::vector have issues?
std::vector<bool> specifically has issues in that it does not conform to a std::vector<T>.
Yes it is specialized. Why should that be a problem?
And for someone coming from a Java background template specialization is not something that should be introduced as a beginning topic
Avoid using vector<bool>,using deque<bool> or bitset
|
0

Welcome! You have entered a whole new world now that you are programming in C++. Let me introduce you to the C++ standard library (often called the STL) (http://www.cplusplus.com for reference). For most containers that you want to use in your everyday life you would probably want to consider one from the standard library.

In this particular instance, you cannot instantiate an array at runtime as you have done above. You cannot instantiate an array on the stack with a size that is determined at runtime. You will need to dynamically allocate memory on the heap or simply use a STL container (std::vector<> is advised). This is how I would have written your code

#include <iostream> #include <cmath> #include <vector> using namespace std; int main() { int a; cout << "Please enter the length of the array: " << endl; cin >> a; vector<bool> array(a); for (int n = 0; n < a; n++) { array[n] = true; } array[0] = false; array[1] = false; for (int k = 2; k < a; k++) { if (array[k] == true){ for (int i = 0; pow(k,2)+ i*k < a; i++) { array[ static_cast<size_t>(pow(k,2) + i * k) ] = false; } } } for (int j = 0 ; j < a ; j++){ if (array[j] == true){ cout << j <<endl; } } return 0; } 

To explain more here. The following line

std::vector<bool> array(n) 

initializes the vector (for the sake of simplicity) with n elements.

More information about the vector class can be found here (http://www.cplusplus.com/reference/vector/vector/?kw=vector)

5 Comments

Thank you ! i'll have a look into vectors.
No problem! You will enjoy C++ :)
If you want more information feel free to comment here and I will provide more information about the C++ standard library containers!
Thank you! you have been very helpful. :-)
Btw about my program...i tried your code. it works perfectly..however it is supposed to display all the prime number between 0 and no. entered by user.This method is based on Sieve of Eratosthenes.It works well enough but 25 is the only composite number being displayed. Rest all are prime. Any idea where i may have went wrong?
0

Can be done as follows.

for (int i = 0; (pow(k,2) + (i*k)) < a; i++) { int kk = (pow(k,2) + (i*k)); array[kk] = false; 

/* This is because pow() is returning double, double + int = double and we are considering double as index of array, which is not allowed in the standard.*/

1 Comment

A program like this may behave differently depending on compiler, compiler options, etc. Floating point calculations are not exact, and kk may have differing results.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.