C: When is a variable or value considered used? - c

I am cleaning up some code from a Coverity issue and have a situation where a pointer local to a function is used earlier on is a function for comparison, then later on it is assigned to point else where but it is never de-referenced or used to assign something to its value. Coverity is saying that it is an unused pointer value - so I am thinking to cast it to a void to indicate the pointer is not used after that point. I am wondering when is a value or variable considered used in a program? Here is a code sample explaining my situation:
In the sample below Coverity would flag the fltr_ptr as not being used after its two assignments at the end of the sample
int initialise (void)
{
// pointer first decalred and defined
FILTER_PTR fltr_ptr = NULL;
// pointer given valid value
fltr_ptr = global_val->filter_group[index];
// second use of fltr_ptr
if ( TRUE == fltr_ptr -> being_used)
{
// first use of fltr_ptr
if ( TRUE != close_filter ( fltr_ptr -> Filter)
{
// print error
}
// do more code
// fltr_ptr assigned first time , value not used should it be (void)fltr_ptr?
fltr_ptr = Free_Memory (fltr_ptr, sizeof(FILTER_PTR));
}
else
{
return 1;
}
for ( number of iterations )
{
// fltr_ptr assigned again but value not used should it be (void)fltr_ptr?
fltr_ptr = global_val->filter_group[index];
}
return 0;
}

Coverity points to you that you assign to fltr_ptr in the last for loop but you do nothing with this value. Why assign at all? Casting to void could possibly fix the warning, but the first thing to fix should be either to use the pointer somehow, or stop assigning to it.

To answer the title question, a variable is considered unused when "it is initialised or assigned to and then disposed of without being read."
int main()
{
int i;
int j = 1; // both i and j are unused at this point
int i = j * 2; // j is now 'used', the new value of i is unused
printf("%d",j);//j is used again
} // i goes out of scope without being used.
note that the definition isn't also "if it is assigned to without being read" as this would indicate that there was a problem with the following:
unsigned int find_max_index(int a[], int size)
{
unsigned int i;
unsigned int maxval = 0;
unsigned int maxindex = 0;
for (i = 0; i< size; i++){
if (a[i]>maxval){
maxval = a[i];
maxindex = i;
}
}
return maxindex;
}
As in this code maxindex can be assigned to multiple times without being read.
Looking back at my original example, we can eliminate i without any change to the program. This reduces the complexity of the program, removes redundant operations (though the compiler should do this when optimising too) and reduces the chance of programmer error in the future:
//FUNCTIONALLY THE SAME AND SIMPLER
int main()
{
int j = 1; // j is unused at this point
printf("%d",j);// j is used
}
In the same way, you can remove this entire loop:
for ( number of iterations )
{
// fltr_ptr assigned again but value not used should it be (void)fltr_ptr?
fltr_ptr = global_val->filter_group[index];
}
(You remove the assignment and get an empty loop. as this is a long nop, it can also be removed)

Related

First Element of array not empty, pointer dereference

i am writing code for a microcontroller.
I have the following example so far:
// weekly table[timeslot][day]
const int _rows = 7;
const int _cols = 12;
const int _num_weekly_table = _rows * _cols;
uint32_t weekly_table[_rows][_cols];
// pointer pointing start of array weekly array
uint32_t *ptr_weekly_table = &weekly_table[0][0];
int progress_weekly_table = 0;
bool weekly_table_full = false;
/*
* according to progress_weekly_table save a value in the weekly_table
*/
void append_weekly_table( uint32_t value)
{
//insert element
printf(*ptr_weekly_table);
*(ptr_weekly_table + progress_weekly_table) = value;
//increase progress
progress_weekly_table++;
//if the table is full set flag
if (progress_weekly_table > _num_weekly_table) {
weekly_table_full = true;
}
}
During the main loop I run this line:
append_weekly_table(1);
But the resulting array does not have a 1 as the first element, instead a 3200171746 (reproducable).All other elements in the array are 1 if i continue to run append_weekly_array.
What is my error here? Quite new to pointers so I don't know if this is the issue.
For starters these declarations
const int _num_weekly_table = _rows * _cols;
uint32_t weekly_table[_rows][_cols];
are invalid if they are declarations in the global namespace because 1) you may not initialize a variable with the static storage duration with a non-constant expression and 2) you may not declare Variable Length Arrays with the static storage duration.
It seems you are compiling your program as a C++ program instead of as a C program.
In any case the function append_weekly_table is invalid.
For example this statement
printf(*ptr_weekly_table);
does not make sense because the first parameter of the function has type const char *.
int printf(const char * restrict format, ...);
^^^^^^^^^^^^
And initially the object *ptr_weekly_table has inderterminate value (if the program is a C program and the array does not have the static storage duration; otherwise the object is zero initialized).
Also this condition
if (progress_weekly_table > _num_weekly_table) {
weekly_table_full = true;
}
also is wrong. It should be written like
if (progress_weekly_table == _num_weekly_table) {
weekly_table_full = true;
}
If you want to compile your program as a C program then the variables _rows and _cols must be declared at least like
enum { _rows = 7, _cols = 12 };
Also it is a bad idea to use leading underscores in variable names because such names are reserved by the system.
Here is a demonstrative C program that can compile.
#include <stdio.h>
#include <stdbool.h>
#include <stdint.h>
enum { _rows = 7, _cols = 12 };
const int _num_weekly_table = _rows * _cols;
uint32_t weekly_table[_rows][_cols];
// pointer pointing start of array weekly array
uint32_t *ptr_weekly_table = &weekly_table[0][0];
int progress_weekly_table = 0;
bool weekly_table_full = false;
void append_weekly_table( uint32_t value)
{
*(ptr_weekly_table + progress_weekly_table) = value;
//increase progress
progress_weekly_table++;
//if the table is full set flag
if (progress_weekly_table == _num_weekly_table) {
weekly_table_full = true;
}
}
int main(void)
{
append_weekly_table( 1 );
printf( "ptr_weekly_table[0] = %d\n", *ptr_weekly_table );
return 0;
}
The program output is
ptr_weekly_table[0] = 1
You could substitute these two statements
*(ptr_weekly_table + progress_weekly_table) = value;
//increase progress
progress_weekly_table++;
//if the table is full set
with one statement
ptr_weekly_table[progress_weekly_table++] = value;
The main problem is most likely this this:
printf(*ptr_weekly_table);
The expression *ptr_weekly_table an uint32_t value. Not a string (char *) which printf expects. Because you in effect pass a null pointer (since ptr_weekly_table[0] is supposedly zero) then you will ask printf to print whatever "string" is at location zero, and that will lead to undefined behavior.
To print the correct value use something like
printf("%"PRIu32"\n", ptr_weekly_table[0]);
See e.g. this format specifier macro reference for information about PRIu32.
And as you can see I used ptr_weekly_table[0] to get the first value of the array. The expressions ptr_weekly_table[0] and *ptr_weekly_table are equal.
In fact, for any pointer or array p and index i, the expression p[i] is exactly equal to *(p + i). Which means *(ptr_weekly_table + progress_weekly_table) could be written ptr_weekly_table[progress_weekly_table] (which is a couple of characters less to write, as well as often more readable).

Warning passing argument 2 of 'finder' makes pointer from integer without a cast

I am trying to pass a user entered variable "find" into this function and return the subscript location of the number (in an existing array) that the user entered. I saw some other posts about this but couldn't understand really what was being explained. Sorry, beginner student.
It isn't quite complete but I cannot compile due to a couple of errors that I am not sure about.
Warning passing argument 2 of 'finder' makes pointer from integer without a cast. Its pointing at:
num_loc = finder(find, sort_num[10]);
Here I am setting "num_loc" to the return of "where" in the function
num_loc = finder(find, sort_num[10]);
printf( "\nYour number is located in memory location %d of the array",num_loc );
"[Note] expected 'int *' but argument is of type 'int'" which is pointing to my function prototype.
//fprototype outside the main at the beginning of the file
int finder(int f,int x[]);
Here is my function:
//function located at the end of the file outside the main
int finder(int f, int x[])
{
int found = 0;
int where;
int i = 0;
while (found != 1){
if (x[i] == f){
found = 1;
where = i;
return where;
}
else{
++i;
}
}
}
num_loc = finder(find, sort_num[10]);
is equivalent to
int num = sort_num[10]; // Problem. Accessing array out of bounds.
num_loc = finder(find, num); // Problem. Using an `int` when an `int*` is expected.
// That's what the compiler is complaining about.
You need to use just sort_num in the call to finder.
num_loc = finder(find, sort_num);
The real solution involves changing finder to accept another argument that indicates the number of elements in sort_num. Otherwise, you run the risk of accessing the array out of bounds. It can also be simplified quite a bit.
int finder(int f, int x[], int arraySize)
{
for ( int i = 0; i < arraySize; ++i )
{
if (x[i] == f)
{
return i;
}
}
// Not found
return -1;
}
and then call it with:
num_loc = finder(find, sort_num, 10);
This is the first part of your function definition:
int finder(int f, int x[])
Your second argument is an int pointer, which the compiler is telling you by saying :
expected 'int *'
You called your function with this:
num_loc = finder(find, sort_num[10]);
If sort_num is an integer array, then sort_num[10] evaluates to the integer at the 11th place in that array. So you're passing your finder function that integer, instead of an int pointer. If sort_num is an integer array, re-write your call as:
num_loc = finder(find, sort_num);
This way you will be passing an int pointer that holds the address of the first element in the sort_num array.

C Passing double pointer from function

I am working on a non homework question that I just can't solve no matter what I try.
The problem is one from Project Euler that involves solving for even Fibonacci numbers and summing them together, I chose this one as a chance to learn more about functions, pointers, and working with large numbers that would be best served by not copying their value but instead passing a memory address.
I currently have the following:
/*Second attempt at fibo 4mil
problem.*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <float.h>
//MAX is 20 for testing reasons
//Actual value is MAX 0X3D0900
#define MAX 20
//Function will accept even fibo numbers
//then sum them together for output later
void evenCount (double* evenPoint);
int main(void){
double firstVar = 0;
double secondVar = 1;
double thirdVar;
double modVar = 2;
double sumVar;
double count;
for(count = 0; count < MAX; count++){
thirdVar = firstVar + secondVar;
secondVar = firstVar;
firstVar = thirdVar;
if(fmod(firstVar, modVar) == 0){
evenCount(&firstVar);
}
printf("Currently: %.2f\n", firstVar);
}
sumVar = &evenCount();
printf("Final even sum is: %f\n", sumVar);
return 0;
}
void evenCount (double* evenPoint){
double tempOne, tempTwo, tempThree;
tempOne = *evenPoint;
tempThree = tempOne + tempTwo;
tempTwo = tempOne;
tempOne = tempThree;
evenPoint = &tempOne;
}
I can't tell if the data from main() is being properly passed to the evenCount function for them to be summed and have it's value updated to be printed at the end of main().
My questions are:
Do I need a second double pointer in evenCount to pass the final value or can I just reference one value updating it as it loops through?
Does main() need a pointer so that pointer can reference evenCount pointer?
I would really appreciate any help because I have bought a Safari online subscription, have the "C A Reference Manual" sitting next to me but I just can't figure this out. Plus i read over this question and it kind of answered my question, but the person is using multiple function prototypes.
too few arguments to function and can't be used as a function---- beginning C
Thanks to anybody that looks
I am not completely clear about what the evenCount() function is supposed to do.
Fact is that you are calling it the wrong way - sumVar = &evenCount(); is even twice wrong, as it is missing an argument and the & doesn't make sense - and that it doesn't do what you probably want.
Let's have a look:
void evenCount (double* evenPoint){
double tempOne, tempTwo, tempThree;
Here you define three auto variables, but they haven't got a value yet.
tempOne = *evenPoint;
tempThree = tempOne + tempTwo;
What do you expect to be tempTwo here?
tempTwo = tempOne;
tempOne = tempThree;
evenPoint = &tempOne;
You might mean *evenPoint = tempOne here, but I am not sure.
}
I suppose you want a way to make a "step" in terms of Fibonacci numbers. So let's look:
In order to create the "next" Fib number, you need the two previous ones and add them together. So a "step" could be done in a function like
void fibStep(double * curr, double *prev) {
double new = *curr + *prev;
*prev = *curr;
*curr = new;
}
and then
int main(void){
double firstVar = 0;
double secondVar = 1;
double sumVar = 0;
int count; // no need to have this as a double...
for(count = 0; count < MAX; count++){
fibStep(&secondVar, &firstVar);
if(fmod(secondVar, 2) == 0){
sumVar += secondVar);
}
printf("Currently: %.2f\n", secondVar);
}
printf("Final even sum is: %f\n", sumVar);
return 0;
}
I'm not quite sure what evenCount is meant to do as it is. Edit: see below.
From your description of the problem, it seems like you could just do:
int isEven(unsigned int number)
{
return !(number%2);
}
int main()
{
unsigned int first = 1, second = 1, next, sum = 0;
//we already have the first two numbers so start at 2
for(count = 2; count < MAX; count++)
{
next = first+second;
first = second;
second = next;
//we know the starting values are odd (1 & 1) and won't need to be summed so we can test the new value -
if (isEven(second)) //if even (no remainder when dividing by 2)
{ sum+=first;}
}
printf("Final even sum is: %f\n", sum);
}
Note, there is no need for double here (yet). The sum (at n=20) is still far too low to exceed what int can store. (although at this point it is growing quickly)
As for your actual questions:
note: when you don't need a pointer, it is recommended that you don't use one, as all you are going to do is make the code more complex than needed
Do I need a second double pointer in evenCount to pass the final value?
If the function is meant to keep track of the sum, then I'd do it like this:
unsigned int evenSum(unsigned int num = 0)
{
static unsigned int sum = 0; //initialised on first use of function. Value is retained between function calls.
//we test for even here - no longer need to test in calling code
// - making the algorithm simpler
if (isEven(num))
sum += num;
return sum;
}
which can then be called like this:
//adding values:
evenSum( new_value );
//retrieving sum
sum = evenSum();
//or do both:
sum = evenSum( new_value );
If you wanted to store the sum 'locally' though (i.e. as a variable in main, but modify it in the evenSum() function), then yes, you would then need to pass it into the funtion too as a pointer:
void evenSum(unsigned int num, unsigned int * sum)
{
if (isEven(num))
*sum += num;
}
It would be called like this:
sum = 0;
num = 56;
evenSum(num, &sum); //sum is now sum+num
As you pass the address of sum in, when the function de-references it, it modifies the value and not a copy. The number passed in does not need to be passed in as a pointer as it is a (forgetting correct word here, but it means 'basic') type, and passing it by value is actually slightly more efficient as at runtime it can just be loaded into a register, and doesn't rely on memory lookup. Plus, it is easier to read.
Does main() need a pointer so that pointer can reference evenCount pointer?
To be honest, I'm not 100% sure what you are asking here.
If you are asking:
Do I need to store a pointer to the sum in main() to pass into the evenSum() function?
then no.
You can pass a pointer to a 'thing' using the "address of" operator &. I've used it above in the second calling example in the above answer:
unsigned int * sum_pointer = ∑// <--- not needed
evenSum(num, &sum); //sum is now sum+num
^
This passes a pointer to sum
Edit: looking at your code again, is evenCount meant to find the next fibonachi number?
If so, you could do:
void next_fib(unsigned int *previous, unsigned int *current)
{
unsigned int next = *previous+*current;
*previous = *current;
*current = next;
}
And you would call this like so:
unsigned int val1 = 1, val2 = 1;
next_fib(&val1, &val2); //val2 is now the 3rd fib. #
next_fib(&val1, &val2); //val2 is now the 4th fib. #
To add this to my code from above, the program becomes:
int isEven(double number)
{
return !(number%2);
}
unsigned int evenSum(double num = 0)
{
static double sum = 0;
//we test for even here - no longer need to test in calling code
// - making the algorithm simpler
if (isEven(num))
sum += num;
return sum;
}
void next_fib(unsigned int *previous, unsigned int *current)
{
unsigned int next = *previous+*current;
*previous = *current;
*current = next;
}
int main()
{
unsigned int first = 1, second = 1;
//we already have the first two numbers so start at 2
for(count = 2; count < MAX; count++)
{
next_fib(&first, &second);
evenSum(second);
}
printf("Final even sum is: %f\n", evenSum());
}
Edit 2:
After reading your edit and some of your comments, and then taking a look at the actual task, you have interpreted the question incorrectly.
The question asks for the sum of all even numbers in the fibbonachi sequence, where the number is less than 4x106. This is thankfully easier and quicker to do than the sum of all the even Fibonacci numbers up to the 4x106th.
Obviously, we need to change the algorithm. Luckily, we split the main bits into functions already, so it's pretty simple, mainly just a change in the loops, though I made a couple more changes too:
bool isEven(unsigned long number)
{
return !(number%2);
}
void next_even_fib(unsigned long *previous, unsigned long *current)
{
do
{
unsigned int next = *previous+*current;
*previous = *current;
*current = next;
} while (!isEven( *current));
//we could just do 3 passes here without needing the isEven() function
//as the Fibonacci sequence is always O,O,E,O,O,E...
//but this is a more general form
}
int main()
{
//as there is less constraint on knowing which term we are on, we can skip straight to the first even number.
unsigned long first = 1, second = 2;
unsigned long sum = 0;
do
{
//with the sum calculation first, we can break out of the loop before the sum
//we've changed the algorithm so when we get here, second is always even
sum += second;
next_even_fib(&first, &second);
} while (second < 4000000);
printf("Final even sum is: %d\n", sum);
}
Note that I changed the types to unsigned long. This is still an integer value, but one that is guaranteed to be long ( :-P ) enough to store the numbers we need.
Passing of the value is correct but you can't do evenPoint = &tempOne; to return a value from the function. There are two problems in doing that: first is that C supports only pass by value, so when you pass a pointer you are in fact creating a copy of the pointer for the callee. Any modification of the data pointed will be visible to the caller but not modifications to the pointer argument itself. When you modify the pointer argument you are in fact modifying a stack variable that the caller has no access to.
What's the difference between passing by reference vs. passing by value?
You could change your code in the following way:
void evenCount (double** evenPoint){
double tempOne, tempTwo, tempThree;
tempOne = **evenPoint;
tempThree = tempOne + tempTwo;
tempTwo = tempOne;
tempOne = tempThree;
*evenPoint = &tempOne;
}
But that would mean that *evenPoint points to a variable allocated on the stack, precisely on the frame of evenCount. When evenCount returns the frame get popped out of the stack. Accessing that variable after it is outside the stack will cause undefined behavior.
Consider the following example where you call another function A() after evenCount before using evenPoint. A() function frame would be placed in memory at the same location of where evenCount frame was and its local variables might overwrite the value of evenPoint. When you subsequently read evenPoint you will find its value changed.
C++ Returning reference to local variable
Finally, you read the variable tempTwo which is an uninitialized automatic variable so you'll end up reading garbage.

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

Passing pointers of arrays in C

So I have some code that looks like this:
int a[10];
a = arrayGen(a,9);
and the arrayGen function looks like this:
int* arrayGen(int arrAddr[], int maxNum)
{
int counter=0;
while(arrAddr[counter] != '\0') {
arrAddr[counter] = gen(maxNum);
counter++;
}
return arrAddr;
}
Right now the compilier tells me "warning: passing argument 1 of ‘arrayGen’ makes integer from pointer without a cast"
My thinking is that I pass 'a', a pointer to a[0], then since the array is already created I can just fill in values for a[n] until I a[n] == '\0'. I think my error is that arrayGen is written to take in an array, not a pointer to one. If that's true I'm not sure how to proceed, do I write values to addresses until the contents of one address is '\0'?
The basic magic here is this identity in C:
*(a+i) == a[i]
Okay, now I'll make this be readable English.
Here's the issue: An array name isn't an lvalue; it can't be assigned to. So the line you have with
a = arrayGen(...)
is the problem. See this example:
int main() {
int a[10];
a = arrayGen(a,9);
return 0;
}
which gives the compilation error:
gcc -o foo foo.c
foo.c: In function 'main':
foo.c:21: error: incompatible types in assignment
Compilation exited abnormally with code 1 at Sun Feb 1 20:05:37
You need to have a pointer, which is an lvalue, to which to assign the results.
This code, for example:
int main() {
int a[10];
int * ip;
/* a = arrayGen(a,9); */
ip = a ; /* or &a[0] */
ip = arrayGen(ip,9);
return 0;
}
compiles fine:
gcc -o foo foo.c
Compilation finished at Sun Feb 1 20:09:28
Note that because of the identity at top, you can treat ip as an array if you like, as in this code:
int main() {
int a[10];
int * ip;
int ix ;
/* a = arrayGen(a,9); */
ip = a ; /* or &a[0] */
ip = arrayGen(ip,9);
for(ix=0; ix < 9; ix++)
ip[ix] = 42 ;
return 0;
}
Full example code
Just for completeness here's my full example:
int gen(int max){
return 42;
}
int* arrayGen(int arrAddr[], int maxNum)
{
int counter=0;
while(arrAddr[counter] != '\0') {
arrAddr[counter] = gen(maxNum);
counter++;
}
return arrAddr;
}
int main() {
int a[10];
int * ip;
int ix ;
/* a = arrayGen(a,9); */
ip = a ; /* or &a[0] */
ip = arrayGen(ip,9);
for(ix=0; ix < 9; ix++)
ip[ix] = 42 ;
return 0;
}
Why even return arrAddr? Your passing a[10] by reference so the contents of the array will be modified. Unless you need another reference to the array then charlies suggestion is correct.
Hmm, I know your question's been answered, but something else about the code is bugging me. Why are you using the test against '\0' to determine the end of the array? I'm pretty sure that only works with C strings. The code does indeed compile after the fix suggested, but if you loop through your array, I'm curious to see if you're getting the correct values.
I'm not sure what you are trying to do but the assignment of a pointer value to an array is what's bothering the compiler as mentioned by Charlie. I'm curious about checking against the NUL character constant '\0'. Your sample array is uninitialized memory so the comparison in arrayGen isn't going to do what you want it to do.
The parameter list that you are using ends up being identical to:
int* arrayGen(int *arrAddr, int maxNum)
for most purposes. The actual statement in the standard is:
A declaration of a parameter as "array of type" shall be adjusted to "qualified pointer to type", where the type qualifiers (if any) are those specified within the [ and ] of the array type derivation. If the keyword static also appears within the [ and ] of the array type derivation, then for each call to the function, the value of the corresponding actual argument shall provide access to the first element of an array with at least as many elements as specified by the size expression.
If you really want to force the caller to use an array, then use the following syntax:
void accepts_pointer_to_array (int (*ary)[10]) {
int i;
for (i=0; i<10; ++i) {
(*ary)[i] = 0; /* note the funky syntax is necessary */
}
}
void some_caller (void) {
int ary1[10];
int ary2[20];
int *ptr = &ary1[0];
accepts_pointer_to_array(&ary1); /* passing address is necessary */
accepts_pointer_to_array(&ary2); /* fails */
accepts_pointer_to_array(ptr); /* also fails */
}
Your compiler should complain if you call it with anything that isn't a pointer to an array of 10 integers. I can honestly say though that I have never seen this one anywhere outside of various books (The C Book, Expert C Programming)... at least not in C programming. In C++, however, I have had reason to use this syntax in exactly one case:
template <typename T, std::size_t N>
std::size_t array_size (T (&ary)[N]) {
return N;
}
Your mileage may vary though. If you really want to dig into stuff like this, I can't recommend Expert C Programming highly enough. You can also find The C Book online at gbdirect.
Try calling your parameter int* arrAddr, not int arrAddr[]. Although when I think about it, the parameters for the main method are similar yet that works. So not sure about the explanation part.
Edit: Hm all the resources I can find on the internet say it should work. I'm not sure, I've always passed arrays as pointers myself so never had this snag before, so I'm very interested in the solution.
The way your using it arrayGen() doesn't need to return a value. You also need to place '\0' in the last element, it isn't done automatically, or pass the index of the last element to fill.
#jeffD
Passing the index would be the preferred way, as there's no guarantee you won't hit other '\0's before your final one (I certainly was when I tested it).

Resources