What is the default value of an uninitialized boolean array, in C? - c

I have something like,
#include <stdio.h>
#include <stdbool.h>
int main()
{
int t,answer;
bool count;
long long int L;
scanf("%d",&t);
while(t>0)
{
answer = 0;
scanf(" %lld",&L);
bool count[L];
// .....restofthecode. NDA Constraint.
What would be the default value of all the elements of arr[x]?
Is it false always? Or true? Or any random value?

There is no type named boolean in C but there is _Bool and in stdbool.h a macro bool that expands to _Bool.
#include <stdbool.h>
#define X 42
bool arr[X];
arr elements have an initial value of false (that is 0) if declared at file scope and indeterminate if declared at block scope.
At block scope, use an initializer to avoid the indeterminate value of the elements:
void foo(void)
{
bool arr[X] = {false}; // initialize all elements to `false`
}
EDIT:
Now the question is slightly different:
long long int x;
scanf("%lld",&x);
bool arr[x];
This means arr is a variable length array. VLA can only have block scope, so like any object at block scope it means the array elements have an indeterminate value. You cannot initialize a VLA at declaration time. You can assign a value to the array elements for example with = operator or using memset function.

As per your code, in local scope
boolean arr[x];
itself is invalid. x is used uninitialized.
Just FYI, in global [file] scope, all the variables are initialized to 0. In local scope, they simply contain garbage, unless initialized explicitly.
EDIT:
[After the edit] All the variables in the arr array will have garbage value. It is in local scope [auto].

Related

Variable hiding and "priority" in c [duplicate]

This question already has answers here:
Scope of variables in "for" loop
(2 answers)
New block scope for selection and iteration statement
(2 answers)
Closed 2 years ago.
The following program:
#include <stdio.h>
int main()
{
char i='u';
for (int i=0;i<=3;i++)
{
printf("%d\n",i);
}
return 0;
}
prints 0,1,2,3 in new lines, since the character variable i declared outside the for loop is "hid". But, the following program:
#include <stdio.h>
int main()
{
char i='u';
for (int i=0;i<=3;i++)
{
int i=8;
printf("%d\n",i);
}
return 0;
}
print 8 '4' times on new lines as if the variable i initialized as 8 has more priority than the variable i (counter) going from 0 to 3 .
The i in the for initialization and the i in the for loop are in the same block, but one seems to have more priority than the other. Does such a priority really exist and if yes, is there a defined order of priority?
What you're calling "priority" is actually referred to as scope.
Each variable and function has an enclosing scope in which the name is valid and in which it has a particular lifetime. If a variable in one scope has the same name as a variable at a higher scope, the variable(s) at the outer scope(s) is masked and only the one in the innermost scope is visible.
In the case of a variable declared in the initialization section of a for loop, these variables have a scope that is visible in the other parts of the for as well as the loop body. If the loop body is a compound statement, that starts another scope, and variables declared here will mask variables with the same name at higher scopes.
So in your second program you have three variables named i:
The scope of the first i is the body of the main function.
The scope of the second i is for statement.
The scope of the third i is the body of the for statement.
Such priority is defined by scoping rules:
The scope of any other identifier begins just after the end of its declarator and before the initializer, if any:
int x = 2; // scope of the first 'x' begins
{
int x[x]; // scope of the newly declared x begins after the declarator (x[x]).
// Within the declarator, the outer 'x' is still in scope.
// This declares a VLA array of 2 int.
}
unsigned char x = 32; // scope of the outer 'x' begins
{
unsigned char x = x;
// scope of the inner 'x' begins before the initializer (= x)
// this does not initialize the inner 'x' with the value 32,
// this initializes the inner 'x' with its own, indeterminate, value
}
unsigned long factorial(unsigned long n)
// declarator ends, 'factorial' is in scope from this point
{
return n<2 ? 1 : n*factorial(n-1); // recursive call
}

The variable 'pminutes' is being used without being initialized

I keep getting this error message:
The variable 'pminutes' is being used without being initialized.
This is my code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
void ConvertMinutesToHM(int time_minutes, int *phours, int *pminutes);
void main ()
{
int min, *phours, *pminutes;
printf("Enter a number of minutes:\n");
scanf("%d", &min);
ConvertMinutesToHM(min, phours, pminutes);
printf("Hours=%d", phours);
printf("Minutes=%d", pminutes);
}
void ConvertMinutesToHM (int time_minutes, int *phours, int *pminutes)
{
int hours, minutes;
*phours = time_minutes / 60;
*pminutes = time_minutes % 60 * 60;
}
In the c programming language, variables that are not global or static or explicitly initialized by the programmer are not initialized at all and reading them would cause undefined behavior.
You are passing it to a function that will dereference the pointer and since it was not initialized the function would read from an undetermined location in memory, because the value the pointer is holding is not defined anywhere. This does not mean that the pointer is not holding a value, it means that the value is a random garbage value that cannot be used as an address but will be if you are not careful and dereference it.
You can initialize it by making it point to an actual variable that would be allocated on the stack and make it point to valid memory, the like this
int minutes;
int *pminutes = &minutes;
of course, you can simply pass &minutes directly but this way, the pminutes pointer will be holding the address of a stack variable minutes which is properly allocated, but uninitialized.
The minutes variable is not required to be initialized because it's intended to be used as storage for the value the function will read and store into whatever pminutes is pointing to.
The problem is then that pminutes is a pointer, and not initializing it will cause undefined behavior when the program attempts to read the address it is holding.
It's still good practice to explicitly initialize most variables, but I also consider good practice not to do it when you are certain that they will be initialized somewhere and adding a explicit initialization would not be meaningful, thus making the code harder to understand.
Because you haven't initialised pminutes in main before passing it to ConvertMinutesToHM() function. Remember you need to initialise all parameters before passing them to a function - otherwise how does the function know what values to work on?
In main you should really just need normal int and initialise them properly:
int min = 0, phours = 0, pminutes = 0;
In when calling ConvertMinutesToHM(), you can pass in the address of the corresponding variables:
ConvertMinutesToHM(min, &phours, &pminutes);
Edit: You made other mistakes, too in that ConvertMinutesToHM() function: local hours, minutes are completely not needed, and the calculation of pminutes makes no sense.
Sample fix:
void ConvertMinutesToHM(int time_minutes, int *phours, int *pminutes);
int main()
{
int min = 0, phours = 0, pminutes = 0;
printf("Enter a number of minutes:\n");
scanf("%d",&min);
ConvertMinutesToHM(min,&phours,&pminutes);
printf("Hours=%d\n",phours);
printf("Minutes=%d\n",pminutes);
}
void ConvertMinutesToHM (int time_minutes, int *phours, int *pminutes)
{
*phours=time_minutes/60;
*pminutes=time_minutes%60;
}
The following code:
cleanly compiles
performs the desired operation
incorporates the comments on the OPs question
and now the code
#include <stdio.h> // printf(), scanf(), perror()
#include <stdlib.h> // exit(), EXIT_FAILURE
//#include <math.h>
void ConvertMinutesToHM(int time_minutes, int *phours, int *pminutes);
int main ( void )
{
int min;
int hours;
int minutes;
printf("Enter a number of minutes:\n");
if( 1 != scanf("%d", &min) )
{
perror( "scanf failed to read the minutes from the user" );
exit( EXIT_FAILURE );
}
// implied else, scanf successful
ConvertMinutesToHM(min, &hours, &minutes);
printf("Hours=%d\n", hours);
printf("Minutes=%d\n", minutes);
} // end function: main
void ConvertMinutesToHM (int time_minutes, int *phours, int *pminutes)
{
//int hours, minutes;
*phours = time_minutes / 60;
*pminutes = time_minutes % 60;
} // end function: ConvertMinutestoHM
and here is the results that are displayed on the terminal:
Enter a number of minutes:
100
Hours=1
Minutes=40
You are using pointer that is uninitialised. Pointers with static storage are initialized with null pointers. Pointers with automatic storage duration are not initialized.
From C89 Standard:
C89 §3.5.7 Initialization
If an object that has static storage duration is not initialized explicitly, it is initialized implicitly as if every member that has arithmetic type were assigned 0 and every member that has pointer type were assigned a null pointer constant. If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate.
See Also ISO C 99 6.7.8.10:
If an object that has automatic storage duration is not initialized explicitly, its value is
indeterminate. If an object that has static storage duration is not initialized explicitly,
then:
if it has pointer type, it is initialized to a null pointer;
You are defining int *pminutes and not initialising it so its value is indeterminate and after that doing *pminutes = time_minutes%60*60 try to access that indeterminate location and result in undefined behaviour.

Let static function variable take value of parameter in C

I am writing a data mashing function where I'm modifying audio data over time for a sort of dynamic bit-crusher audio filter. It is convenient for me to use static variables because their values carry over between function calls and this helps me achieve some interesting time-based effects by incrementing and so forth across rendering callbacks.
For example, one effect uses a sin function to modulate some sound effect over time. Like so:
void mangle(float * data, int n) {
static bool direction = false;
static float bottom = 0;
static float top = n;
static float theta = 0;
theta += 5;
// data = sin(theta) etc..
So I wish theta to be initialized once and than modified over time. Likewise, top wants to be static variable because I modify it later in the function also. In addition, top should take on the value of parameter n because n changes based on program state. But when I go to assign n to top, I get the compiler error
Initializer element is not a compile-time constsant.
Is there a way to assign a parameter to a static variable? Is there another way to accomplish what I want without static variables? I am aware I could use instance variables but I find that to be too much.
static variables are initialized before the program execution begins, so you cannot use a variable value to initialize a static variable. You'll need a compile-time constant value to initialize the static variable.
Quoting C11 standard, chapter §6.2.4, Storage durations of objects (emphasis mine)
[..] or with the storage-class
specifier static, has static storage duration. Its lifetime is the entire execution of the
program and its stored value is initialized only once, prior to program startup.
However, you can always assign a new value to the static variable.
That said, coming to the initialization part, as per chapter §6.7.9,
If an object that has static or thread storage duration is not initialized
explicitly, then
- ...
- if it has arithmetic type, it is initialized to (positive or unsigned) zero
- ...
so, you need not initialize the static floats explicitly to 0. You can assign any value, whatsoever later in the code.
In your case, top is a local static variable.
It is like global static variable and global variable that they all have static storage duration and they have value before the code startup.
The reason you have error similar to this case:
int a;
int b = a; \\initializer is not a constant
int main() {
...
}
With your purpose, use top as a global variable is a right way to go.
What you should do is create a struct that holds the data that is needed across calls and pass a pointer to the struct to the function. If you wnat to get fancy, you can create functions that allocate, initialize and free such a struct (and the user of the functions never needs to know what the contents of the struct are.
Something like:
struct mangle_t {
bool direction;
float bottom;
float top;
float theta;
};
struct mangle_t* mangle_open(void)
{
struct mangle_t* m = malloc(sizeof *m);
if (m) {
memset(m, 0, sizeof *m);
}
return m;
}
void mangle_close(struct mangle_t* m)
{
free(m);
}
void mangle(struct mangle_t* m, float * data, int n) {
m->top = n;
m->theta += 5;
}
As far as assigning a parameter to a static variable, you can just perofrm the assignment like any other variable (however, not as an initialization in the variable's declaration - that only happens once).
I'm not sure if you want to initialize top once and then keep it, but if so, this is what I would do:
void mangle(float *data, int n) {
static float top = -1; // Assuming that n will never be -1
if (top == -1)
top = n;
// .....
}
If you don't need to keep the value of top over function calls, there is no need to declare it static.

function assign to variable in C

Why the following code return error when variable is declared global.
int add(int x, int y) {
return x+y;
}
int ab = add(10, 20);
int main(void) {
printf("%d", ab);
}
But if I call like this:
int add(int x, int y) {
return x+y;
}
int main(void) {
int ab = add(10, 20); // Variable declare inside main
printf("%d", ab);
}
then it executes without an error.
Initializers for global variables must be constant, they can't be an arbitrary expression.
In C language you cannot execute code in the global scope, outside a function and store the return value of the function in a global variable.
Global variables must be constant at initialisation, and when you're doing :
x = func ( ... )
The return of the function is not constant.
From section 3.5.7 Initialization of the C standard:
All the expressions in an initializer for an object that has static storage duration or in an initializer list for an object that has aggregate or union type shall be constant expressions.
and ab has static storage duration but add() is not a constant expression.
Global variables can be initialized by a constant expression. As their values are set at the compilation time, and not in run-time.

Define integer (int); What's the default value?

int i;
int data[5] = {0};
data[0] = i;
What's the value in data[0]?
Also, what's the meaning of this line?
if (!data[0]) { ... }
In most cases, there is no "default" value for an int object.
If you declare int i; as a (non-static) local variable inside of a function, it has an indeterminate value. It is uninitialized and you can't use it until you write a valid value to it.
It's a good habit to get into to explicitly initialize any object when you declare it.
It depends on where the code is written. Consider:
int i;
int data[5] = {0};
void func1(void)
{
data[0] = i;
}
void func2(void)
{
int i;
int data[5] = {0};
data[0] = i;
...
}
The value assigned to data[0] in func1() is completely deterministic; it must be zero (assuming no other assignments have interfered with the values of the global variables i and data).
By contrast, the value set in func2() is completely indeterminate; you cannot reliably state what value will be assigned to data[0] because no value has been reliably assigned to i in the function. It will likely be a value that was on the stack from some previous function call, but that depends on both the compiler and the program and is not even 'implementation defined'; it is pure undefined behaviour.
You also ask "What is the meaning of this?"
if (!data[0]) { ... }
The '!' operator does a logical inversion of the value it is applied to: it maps zero to one, and maps any non-zero value to zero. The overall condition evaluates to true if the expression evaluates to a non-zero value. So, if data[0] is 0, !data[0] maps to 1 and the code in the block is executed; if data[0] is not 0, !data[0] maps to 0 and the code in the block is not executed.
It is a commonly used idiom because it is more succinct than the alternative:
if (data[0] == 0) { ... }
if an integer is declared globally then it is initialized automatically with zero
but if it is local then contains garbage value until and unless itis given some value
If an integer is not initialized, its value is undefined as per C
Since you've included the ={0};, the entire array is filled with zeros. If this is defined outside any function, it would be initialized with zeros even without the initializer. if (!data[x]) is equivalent to if (data[x] == 0).
// File 'a.c'
#include <stdio.h>
void main()
{
int i, j , k;
printf("i = %i j = %i k = %i\n", i, j, k);
}
// test results
> $ gcc a.c
> $ ./a.out
> i = 32767 j = 0 k = 0

Resources