I need to create a shared vector, with the same size as the block.
__global__ func()
{
const int size = blockDim.x;
__shared__ float* Vec[size];
..
}
I get this error
error : expression must have a constant value
I cannot understand where is the problem, sinceblockDim.x is "constant" for each block threads??
Here's how you do it
_shared_ float Vec[size];
remove the star (*)
As far as I know, CUDA does not support variable length arrays (which is what you're trying to do here, regardless of the presence of the keyword const).
If you look at section B.16 of the CUDA C Programming Guide, there's some text on how to specify a size for an extern declared shared array. Although it's a bit more complicated, this is the syntax on how to specify execution-time sized shared arrays. The way you're doing it won't work.
You have to have a compiler that supports C99 to use variable-length arrays. It would seem your compiler doesn't support VLAs, so you have to have an integer constant expression for your array size.
Related
Can I use a variable to define an array's size?
int test = 12;
int testarr[test];
Would this work, I don't want to change the size of the array after initialization. The int test's value isn't known at compile time.
From C99 it is allowed but only for the automatic variables.
this is illegal:
int test = 12;
int testarr[test]; // illegal - static storage variable
int foo(void)
{
int test = 12;
static int testarr[test]; // illegal - static storage variable
}
the only valid form is:
int foo(void)
{
int test = 12;
int testarr[test]; // legal - automatic storage variable
}
can i use an variable to define an arrays size?
This is called Variable Length Arrays (VLA).
Read Modern C then the C11 standard n1570 (and see this reference). VLAs are permitted in §6.7.6; also read the documentation of your C compiler (e.g. GCC).
But you don't want to overflow your call stack, typically limited to a megabyte on laptops (and OS specific).
So you may prefer C dynamic memory allocation with e.g. malloc(3) (and free ...) or calloc.
Beware of memory leaks.
You might be interested by tools such as valgrind. You need to learn to use your debugger (e.g. GDB).
Can I use an integer variable to define an arrays length?
Yes, that is what is called a variable length array and is part of the C standard since C99. Note that an implementation does not need to support it. Therefore you may prefer dynamic memory allocation. Take a look at here:
malloced array VS. variable-length-array
To cite the C standard:
"If the size is not present, the array type is an incomplete type. If the size is * instead of being an expression, the array type is a variable length array type of unspecified size, which can only be used in declarations or type names with function prototype scope;146) such arrays are nonetheless complete types. If the size is an integer constant expression and the element type has a known constant size,the array type is not a variable length array type; otherwise, the array type is a variable length array type. (Variable length arrays are a conditional feature that implementations need not support; see 6.10.8.3.)"
"146) Thus, * can be used only in function declarations that are not definitions (see 6.7.6.3)."
Source: C18, 6.7.6.2/4
Also note:
"Array objects declared with the _Thread_local, static, or extern storage-class specifier cannot have a variable length array (VLA) type."
Source: C18, 6.7.6.2/10
VLAs cannot be used:
at file scope.
when qualified with _Thread_local, static, or extern storage-class specifier.
if they have linkage.
Which means that they can only be used at function-scope and when of storage-class automatic, which is done by default when omitting any explicit specifier.
Feel free to ask for further clarification if you don't understand something.
Without knowing much of the context, wouldn't it be easier to just do this?
#define TEST 12 //to ensure this value will not change at all
int testarr[TEST];
Technically your method should work too but the value of test may change later on depending on the piece of code you written
So, when you try this on C, as in this [https://onlinegdb.com/rJzE8yzC8][1]
It successfully compiles and you can also update the value of the variable int test
However, after the update of test, the size of array does not change since arrays are static-defined.
For guarantee, I suggest you to use either const int or macro variables for doing this.
Is the following legal?
const int n=10;
static int array[n];
If, yes, then why and how?
Note that in C language const objects do not qualify as constants. They cannot be used to build constant expressions. In your code sample n is not a constant in the terminology of C language. Expression n is not an integral constant expression in C.
(See "static const" vs "#define" vs "enum" and Why doesn't this C program compile? What is wrong with this? for more detail.)
This immediately means that your declaration of array is an attempt to declare a variable-length array. Variable length arrays are only allowed as automatic (local) objects. Once you declare your array with static storage duration, the size must be an integral constant expression, i.e. a compile-time constant. Your n does not qualify as such. The declaration is not legal.
This is the reason why in C language we predominantly use #define and/or enum to introduce named constants, but not const objects.
const int n=10;
static int array[n];
This code will encounter an error :
storage size of ‘array’ isn’t constant static int array[n];
^
Static memory allocation refers to the process of reserving memory at compile-time before the associated program is executed, unlike dynamic memory allocation or automatic memory allocation where memory is allocated as required at run-time.
const in C donot make that variable available in compile-time.
Statement like this would not generate that error:
static int array[10];
So, the statement that you have written is illegal or it encounter error while compiling the program.
static vars must ve allocated in COMPILE time, and thus their size and initialization value if any MUST be known at compile time. One could argue that using compile time optimizations the n var would/could be replaced with the constant value 10, and thus it might be possible to successfully compile that specific case.
I am trying to create an array according to the size that the user inputs but it does not seem to be working for c programming. The following are my codes:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int x, y;
scanf("%d", &x);
scanf("%d", &y);
double arr[x][y];
}
The compiler keeps returning an error of" Error: Expression must have a constant value. at the line double ... could anyone help point out the error?
You have two choices:
Either use a decent C compiler that supports C99 (or later) and variable-length arrays (I'd go with this approach, personally);
or if that is not possible, or the resulting array would be too large to fit in a block-scope variable (causing, for example, a stack overflow), you can use malloc(); however, you won't be able to create a true two-dimensional array using that approach, only a pointer-to-pointer, which may or may not be what you are looking for.
The code can work in C99 mode or when the compiler supports VLA(variable length arrays) as an extension (e.g, GCC supports VLA as GNU extesnion).
In C89, you have to use pointers with dynamic memory to simulate.
Older C standards don't provide support for arrays that do not have compile-time sizes:
int array[42];
char text[] = "Hello World";
int numbers = { 1, 2, 3, 4 };
(in the case of the latter two examples, the size is derived from the data)
You either need a newer compiler, to specify the -std=c99 if you are using GCC, or you need to allocate memory for the array yourself.
You're using a C89 (Visual Studio? Though that would give you an error on the declaration of arr next) or a C++ compiler. VLA's (Variable Length Arrays) are a C99 feature.
You need to allocate the memory in run-time . The compiler doesn't allow the declaration of arrays becuase it does not know the size of the array before hand . You need to use malloc() to allocate memory
const int size = 10; // realna ilość danych
int tablica[size+1];
i have:
variable-size type declared outside of any function
Use
#define size 10
instead of a const int. The latter is not a compile-time constant in C, but a variable that cannot be assigned to (unless via a pointer and a cast to get rid of const).
(This is a difference between C and C++.)
You could use an enum.
enum
{
size = 10
};
int table[size + 1];
Use:
enum { size = 10 };
This is a constant value that can be used in declarations and in case labels and so on. In C99, inside a function, the original code would not be a problem -- your array tablica would be a VLA or variable-length array (and the compiler error message is trying to say "you can't have a VLA outside a function").
Using an enum gives better traceability when you use a debugger on your code; the symbol is included in the symbol table. Typically, C preprocessor symbols are not available to the debugger, so trying to print 'size' when it is #define'd doesn't print an answer; printing 'size' when it is an enum does.
See also: "static const" vs "#define" in C
The error is fairly self-explanatory. You can't declare a variable-length array outside of a function. Although the size of the array you're creating is, in practice, fixed at compile time, you've still technically violated the constraints of the language.
The usual choices are:
Move the array into a function. (Usually the best option, remember globals are to be avoided when possible.)
#define size n where n is the size you want, instead of using an int. (Usually better than "magic numbers", and pretty standard practice in traditional C.)
Use a "magic number" (int tablica[11];). (Usually the last choice, though sometimes it does make more sense.)
why can we do this in c?
int n;
scanf("%d",&n);
int a[n];
I thought array is located memory during load time but seems like the above example works during runtime.
Do I misunderstand any thing? can you guys help?
Thanks,
I am no expert in C, but this could be a variable-length array as added by C99 and supported by GCC, for example. GCC allocates the memory for such array on stack, so that it gets automatically freed when you return from the function.
Variable-length arrays are not found in C89, but are a new feature in C99.
I thought array is *al*located memory during load time but seems like the above example works during run-time.
Yes, ordinary arrays like <datatype> <Array_Name> [<size>] is allocated memory during load time it is there in C89 and also existed in C99.
But in the code snippet int a[n]; is a Variable Length Array or VLA for short.VLA's in C99 are defined just like any other array, except that the length doesn’t need to be a compile-time constant.
A decent article on the need of VLAs can be found here :http://www.ddj.com/cpp/184401444 :)
Given how your code is written (specifically, that you have a statement), this must be code within a function.
While I'm not sure if this is strictly required in the spec, within a function, all auto (i.e. function level, not static) arrays are put on the stack. So regardless of whether you have a regular or VL array, the memory is allocated at runtime.
The memory for non-auto arrays is not handled at runtime so do no support VLA. If you try to compile the following code:
extern int size;
char buff1[size];
void doit(int x)
{
static int buff2[x];
int buff3[x];
}
On the compiler I tested this on (gcc 4.2.1), I got following errors:
moo.c:2: error: variably modified ‘buff1’ at file scope
moo.c: In function ‘doit’:
moo.c:6: error: storage size of ‘buff2’ isn’t constant