Warning: Control may reach end of non-void function - c

This is a recursive function that converts binary numbers (given as arrays of integers) into decimals.
double binaryToDecimalRecursive(int *binary, int len) {
if (len == 0)
return *binary;
if (len > 0) {
return (binary[0]*pow(2, len))+binaryToDecimalRecursive(binary+1, len-1);
}
}
The GCC compiler gives me the "control may reach end of non-void function" warning.
What should I fix to prevent that?

It sounds like from the comments you've changed your code to be something like this, correct?
double binaryToDecimalRecursive(int *binary, int len) {
if (len == 0)
return *binary;
if (len > 0) {
return (binary[0]*pow(2, len))+binaryToDecimalRecursive(binary+1, len-1);
}
if(len < 0) return -1;
}
The compiler doesn't recognize that it will always follow at least one of these branches. You can make it more explicit a few ways. Here is one way that should work:
double binaryToDecimalRecursive(int *binary, int len) {
if (len == 0)
return *binary;
else if (len > 0) { // Added an `else` statement
return (binary[0]*pow(2, len))+binaryToDecimalRecursive(binary+1, len-1);
}
else return -1; // Here too
}

If len < 0, the function return nothing.
You should add a clause with abort() if it's smaller than len or simply return a default value.

The compiler is complaining because you are using a non-void function, which must return a value. In C, you must have a value returned. Right now, if len is less than zero, the function would not return a value, which is not allowed.
Luckily, there is an easy fix. If there is no circumstance in which len will be less than zero, you can declare it as an unsigned int -- since an unsigned integer value cannot be less than zero, then your function will cover all possible input values of len. If len can be less than zero, then you need to abort() or return an error code to communicate to the caller of the function that invalid input was given.

The proper solution for your problem, judging from the additional details you provided in the comments, is to use an unsigned integer type and get rid of if (len > 0) check entirely
double binaryToDecimalRecursive(const unsigned *binary, unsigned len) {
return len == 0 ?
*binary :
binary[0] * pow(2, len) + binaryToDecimalRecursive(binary + 1, len - 1);
}
Use unsigned integer types whenever you can, use signed integer types only when you have to.
P.S. Why do you refer to binary[0] as *binary in one place and as binary[0] in another? Is there a reason for such stylistic mishmash in such a small function?

The compiler is complaining because you are using a non-void function and the compiler doesn't know ahead of time that either of two conditions if(len == 0) and if(len > 0) will always be fulfilled. Basically it wants you to have a default return value that doesn't depend on any conditionals, so if somehow you messed up your logic and it does pass both conditionals, the program still has something to return. i.e. you always need a return that does not depend on any conditionals.
A good fix might be to have if(len < 0){ abort() }, and take out if(len > 0) so that becomes the default condition.
double binaryToDecimalRecursive(int *binary, int len) {
if (len == 0) {
return *binary;
}
if (len < 0){
// I assume your program should never logically reach this condition, so this will be good for debugging. It will be more obvious that you reached an unwanted condition than if you returned -1
abort();
}
// since we have specified actions for len <= 0, this is the equivalent of saying len > 0 without letting the compiler complain about it
return (binary[0]*pow(2, len))+binaryToDecimalRecursive(binary+1, len-1);
}

After having done this kind of work now for almost 40 years, I would personally
do it in a simpler and more straight forward way:
Since we want an int output,
long BinarytoDecimal(int binary[], int len)
{
int i, index;
long result;
/**/ - I refer to this as the point of demarcation
result = 0;
for (i = 0, index = len; i < len; i++, index--)
{
result += (long) binary[i] * (long) pow(2,index);
}
return(result);
}
As it is difficult to tell, when someone uses recursion to implement a loop,
this should (and I emphasize should, I think) give you the same result.

matt95,
thought you might be interested. I went ahead and try both sets of code using
GCC, on windows7, under cygwin, and they both DO give identical results for the
same input. The biggest difference, of course, that the code I wrote could not
possibly cause a 'code reaches end of non-void function' error.
Blake Mitchell

Related

What is the best way to return a string value from an int function?

Probably something very straightforward, but I have a recursive function, that returns either the element in an array that is a majority, or returns "None" if there is no majority.
if (count > size_of_input / 2) {
return maj1;
} else if (count2 > size_of_input/2) {
return maj2;
} else {
return -1;
}
Now I want to have the function print "None" instead of -1 if it's the case that there is no majority.
In the main function I am printing these values like so:
printf("%d",merge_sort(&input[0], 0, 24));
How should I optimally go about it?
Apologies if it's not the best question.
There is no standard-compliant way to return a string from an int function. Returning -1 wouldn't work either, because -1 could be a legitimate majority element in an array of int.
One approach to do this is to return the value by setting the result by pointer, and returning a flag indicating a success:
bool find_majority(int data[], size_t length, int* resPtr) {
...
}
The caller would invoke your function as follows:
int res;
if (find_majority(array, array_length, &res)) {
printf("Found: %d\n", res);
} else {
printf("Not found\n");
}
How should I optimally go about it?
The optimal way would be break the original statement into parts rather than trying to wrap everything into one statement. There is possibly a way to do it like you are trying to do, but it is at best messy. I would strive for clarity over compactness. Here is some code to implement this below assuming -1 is a failure condition and that the values in input are non-negative (based on your description, although the domain here is a bit ambiguous):
int majority = merge_sort(&input[0], 0, 24);
if(majority == -1)
printf("None");
else
printf("%d",majority);
This is adding a few extra lines, but this is very clear and gets what you want done.

How to count the number of times number 7 appears in an array

#include <stdio.h>
#include <stdlib.h>
#define LEN 5
int main()
{
int i;
int count = 0;
size_t *ptr = malloc(sizeof(size_t)*LEN);
while(1){
for(i=0;i<LEN;i++){
scanf("%d",&ptr[i]);
}
for(i=0;i < ptr[i]; i++){
if(ptr = NULL || sizeof(ptr) < 0){
printf("nah");
} else if(ptr[i] == 7){
++count;
}
} printf("%d", count);
break;
}
free(ptr);
return 0;
}
What I am trying to do is to find the number of times that the number 7 appears in malloc.. Counting works well but how should I show that if the mallocs size is less than zero, or if its NULL, it has to return -1?
Also, what does it mean by returning -1? I am very new with C programming...
Any help would be so thankful!
C doesn't provide any direct facilities for letting the program know there was an error in a function, so instead we rely on the return values of functions.
For example, in your case, it only makes sense for there to be a size of 0 or greater. If an "error" occurs, you can return -1, and anyone waiting for the result of the program will see the result as invalid, and assume there was an error of some sort.
Because this isn't baked into the C language itself, enforcement is purely by convention. If the person who runs your program doesn't check the value, and uses "-1" like they would use "5", they will run into problems that don't have an obvious cause.
Functions provided by the standard libraries often carry their own conventions for return values and errors. malloc is one of these. Checking the documentation, the "return value" is NULL on a failure. For functions that return pointers, returning NULL as a failure is a common convention.
In your code you can add
size_t *ptr = malloc(sizeof(size_t)*LEN);
if (ptr == NULL) {return -1;}
to properly check the return value.
You want to check for a null value as soon as you can, because using ptr when it could be NULL can lead to segfaults.
Another note, your use of sizeof is suspect in sizeof(ptr) < 0. Sizeof is either called on types like int or size_t, or on variables. In this case, you will get the size of the pointer type, as if you called sizeof(size_t*). Check out documentation.
One last note, you're making ptr of type size_t*. Pointer types are almost like integers, or other number types, so the sizeof(ptr) < 0 condition will never be false. It seems like you're new to C, which uses uses pointers and other low-level concepts that you wouldn't have seen in other languages. Before continuing too much further, I'd recommend solidifying your understanding of memory and pointers in C. Some resources I use are: TutorialsPoint, Class websites, Nice free guides, and wikibooks
Good luck!
There are many issues:
This is pointless inside the for loop, you should do that test right after calling malloc:
if(ptr = NULL || sizeof(ptr) < 0){
printf("nah");
testing sizeof(ptr) < 0 is also pointless (but doesn't hurt here), because the type of sizeof is unsigned and it won't be negative anyway.
It's if (ptr == NULL) instead of if (ptr = NULL).
The while loop is pointless, you are breaking out of it unconditionally.
After printf("nah"); the program should exit and not proceed any further.
And indentation of your program is terrible, it is difficult to read.
This is a corrected version:
#include <stdio.h>
#include <stdlib.h>
#define LEN 5
int main()
{
int i;
int count = 0;
size_t *ptr = malloc(sizeof(size_t)*LEN);
if (ptr == NULL) {
printf("nah");
return 1;
}
for (i = 0; i<LEN; i++) {
scanf("%d", &ptr[i]);
}
for (i = 0; i < LEN; i++) {
if (ptr[i] == 7) {
++count;
}
}
printf("%d", count);
free(ptr);
return 0;
}

Is it cheating to use 'static' when writing a recursive algorithm?

As part of a programming assignment, I'm required to write a recursive function which determines the largest integer in an array. To quote the exact task:
Write a recursive function that finds the largest number in a given list of
integers.
I have come up with two solutions, the first of which makes two recursive calls:
int largest(int arr[], int length){
if(length == 0)
return 0;
else if(arr[length - 1] > largest(arr,length -1))
return arr[length];
else return largest(arr,length -1);
}
The second one makes only one, however it uses a static variable n:
int largest(int arr[], int length){
static int n = -1;
if(length == 0)
return n;
else if (arr[length - 1] > n)
n = arr[length - 1];
return largest(arr, length - 1);
}
I was wondering whether it would be considered cheating use static variables for such a task. Either way, which one is considered better form? Is there a recursive method which tops both?
I wouldn't say that it's cheating to use static variables this way - I'd say that it's incorrect. :-)
Imagine that you call this function multiple times on a number of different arrays. With the static variable introduced, the value of n never resets between calls, so you may end up returning the wrong value. Generally speaking, it's usually poor coding style to set things up like this, since it makes it really easy to get the wrong answer. Additionally, if your array contains only negative values, you may return -1 as the answer even though -1 is actually bigger than everything in the array.
I do think that the second version has one nice advantage over the first - it's much, much faster because it makes only one recursive call rather than two. Consider using the first version, but updating it so that you cache the value returned by the recursive call so that you don't make two calls. This will exponentially speed up the code; the initial version takes time Θ(2n), while the updated version would take time Θ(n).
There is nothing cheating using a static inside function, recursive or otherwise.
There can be many good reasons for why to do so, but in your case I suspect that you are coming up with a wrong solution -- in as largest will only work once in the lifetime of the program running it.
consider the following (pseudo) code;
main() {
largest([ 9, 8, 7]) // would return 9 -- OK
largest([ 1, 2, 3]) // would return 9 ?? bad
}
The reason being that your largest cannot tell the difference between the two calls, but if that is what you want then that is fine.
Edit:
In answer to your comment, something like this will have a better big-O notation than your initial code;
int largest(int arr[], int length){
int split, lower,upper;
switch (length) {
case 1: return arr[0];
case 2: if (arr[1]>arr[0]) return arr[1]; else return arr[0];
default:
if (len <= 0) throw error;
split = length/2;
lower = largest(arr,split);
upper = largest(arr+split,length-split);
if (lower > upper) return lower; else return upper;
}
}
Alternatively, the obvious solution is;
int largest(int arr[], int length){
if (length <= 0) thor error;
int max = arr[0];
for (int i=1; i<length; i++)
if (arr[i] > max) max = arr[i];
return max;
}
which has no recursion at all
It is actually a terrible design, because on the second execution of the function does not return a correct result.
I don't think you need to debate whether it is cheating, if it is wrong.
The first version is also incorrect, because you return arr[length] instead of arr[length-1]. You can eliminate the second recursive call. What can you do instead of calling the same function (with no side-effects) twice with the same arguments?
In addition to the excellent points in the three prior answers, you should practice having more of a recursion-based mind. (1) Handle the trivial case. (2) For a non-trivial case, make a trivial reduction in the task and recur on the (smaller) remaining problem.
I propose that your proper base case is a list of one item: return that item. An empty list has no largest element.
For the recursion case, check the first element against the max of the rest of the list; return the larger. In near-code form, this looks like the below. It makes only one recursive call, and has only one explicit local variable -- and that is to serve as an alias for the recursion result.
int largest(int arr[], int length){
if(length == 1)
// if only one element, return it
return arr[0];
else n = largest(arr,length-1))
// return the larger of the first element or the remaining largest.
return arr[length-1] > n ? arr[length-1] : n
}
Is there a recursive method which tops both?
Recursion gets a bad name when with N elements cause a recursion depth of N like with return largest(arr,length -1);
To avoid this, insure the length on each recursion is halved.
The maximum recursive depth is O(log2(N))
int largest(int arr[], int length) {
if (length <= 0) return INT_MIN;
int big = arr[0];
while (length > 1) {
int length_r = length / 2;
int length_l = length - length_r;
int big_r = largest(&arr[length_l], length_r);
if (big_r > big) big = big_r;
length = length_l;
}
return big;
}
A sneaky and fast method that barely uses recursion as finding the max is trivial with a loop.
int largest(int arr[], int length) {
if (length <= 0) return INT_MIN;
int max = largest(NULL, -1);
while (length) {
length--;
if (arr[length] > max) max = arr[length];
}
return max;
}

What objective circumstances would preclude using a return value also as a diagnostic?

I was going through Linaro ODP framework and saw this code snippet,
static int find_block(const char *name, uint32_t *index)
{
uint32_t i;
for (i = 0; i < ODP_CONFIG_SHM_BLOCKS; i++) {
if (strcmp(name, odp_shm_tbl->block[i].name) == 0) {
/* found it */
if (index != NULL)
*index = i;
return 1;
}
}
return 0;
}
Here, Instead of updating *index, We can return the value of i to achieve the same thing like below.
static int find_block(const char *name)
{
uint32_t i;
for (i = 0; i < ODP_CONFIG_SHM_BLOCKS; i++) {
if (strcmp(name, odp_shm_tbl->block[i].name) == 0) {
/* found it */
return i;
}
}
return -1;
}
Apart from taste, style and coding guidelines -- could there be any objective reasons why one must choose one and cannot choose the other?
The short answer to the question in the title:
You cannot use the return value also as diagnostic if all values in the range of the return type are to be considered valid (in the sense of non-error, non-diagnostic) return values.
Using magic values instead of boolean standard values as error reporting (which is needed if these standard values could be valid results of the function) creates a (slightly) leaky abstraction.
What you see is used when one wants to have multiple return values, or even more likely conditionally many return values.
Your assumption ...
Here, Instead of updating *index, We can return the value of i to achieve the same thing like below.
... is wrong:
*index is an unsigned integer, thus having the range 0 to 2^(32-1) as valid values. Each of these values seems to be a valid index value. Thus you have 2^32 valid results.
In order to indicate failure, without using the "trick" with multiple return values, you'd need to return a value that has no valid meaning, and is thus able to carry the special meaning as indication of a failure. Assuming there is only the indication of failure (and no detailed error value) you'd have 1 invalid result value.
This leaves you with 2^32 + 1 possible result values, which doesn't fit in an 32 bit unsigned integer (and also doesn't fit in the int your example uses).
A possible solution would be to extend the range of the return value, e.g. by using 64 bit unsigned integers. Then you could use value 2^32 (which is outside the range of valid values) to indicate failure:
#define MAGIC_FAILURE (((uint64_t) 1) << 32)
static uint64_t find_block(const char *name)
{
uint32_t i;
for (i = 0; i < ODP_CONFIG_SHM_BLOCKS; i++) {
if (strcmp(name, odp_shm_tbl->block[i].name) == 0) {
/* found it */
return i;
}
}
// return magic value indicating failure
return MAGIC_FAILURE;
}
I'd consider this bad practice, because to understand the function you also need to have the magic value in your head. Also consider debugging this function (or some caller): It's far easier to examine the return value of the original function (which returned data via pointer) and see a boolean value (which one is used to) instead of having to demangle the return value of above function to decide whether it's valid or not.
One final note: In this case though, I'd have gone with a different approach:
static uint32_t find_block(const char *name)
{
uint32_t i;
for (i = 0; i < ODP_CONFIG_SHM_BLOCKS; i++) {
if (strcmp(name, odp_shm_tbl->block[i].name) == 0) {
/* found it */
return i;
}
}
return ODP_CONFIG_SHM_BLOCKS;
}
One could use this because, as the implementation of the loop indicates, not every 32 bit unsigned integer is a valid index (this leaving space for a magic number indicating failure). Using an obviously related constant is a better choice than some random magic value.
Though do also consider the call site:
uint32_t index;
if (! find_block("foo", &index)) {
// OMG
}
// all nice
Here you have only the function name, which is all you need when you want to find a block by its name.
int32_t index = find_block("foo");
if (index == ODP_CONFIG_SHM_BLOCKS) {
// OMG
}
// all nice
Here on the other hand you need two "things" in order to find a block by its name: the function name as well as the magic value. This could be considered a leak in the abstraction.

What is the best way to return an error from a function when I'm already returning a value?

I wrote a function in C that converts a string to an integer and returns the integer. When I call the function I also want it to let me know if the string is not a valid number. In the past I returned -1 when this error occurred, because I didn't need to convert strings to negative numbers. But now I want it to convert strings to negative numbers, so what is the best way to report the error?
In case I wasn't clear about this: I don't want this function to report the error to the user, I want it to report the error to the code that called the function. ("Report" might be the wrong word to use...)
Here's the code:
s32 intval(const char *string) {
bool negative = false;
u32 current_char = 0;
if (string[0] == '-') {
negative = true;
current_char = 1;
}
s32 num = 0;
while (string[current_char]) {
if (string[current_char] < '0' || string[current_char] > '9') {
// Return an error here.. but how?
}
num *= 10;
num += string[current_char] - '0';
current_char++;
}
if (negative) {
num = -num;
}
return num;
}
There are several ways. All have their pluses and minuses.
Have the function return an error code and pass in a pointer to a location to return the result. The nice thing about this there's no overloading of the result. The bad thing is that you can't use the real result of the function directly in an expression.
Evan Teran suggested a variation of this that has the caller pass a pointer to a success variable (which can be optionally NULL if the caller doesn't care) and returns the actual value from the function. This has the advantage of allowing the function to be used directly in expressions when the caller is OK with a default value in an error result or knows that the function cannot fail.
Use a special 'sentinel' return value to indicate an error, such as a negative number (if normal return values cannot be negative) or INT_MAX or INT_MIN if good values cannot be that extreme. Sometimes to get more detailed error information a call to another function (such as GetLastError()) or a global variable needs to be consulted (such as errno). This doesn't work well when your return value has no invalid values, and is considered bad form in general by many people.
An example function that uses this technique is getc(), which returns EOF if end of file is reached or an error is encountered.
Have the function never return an error indication directly, but require the caller to query another function or global. This is similar to how VB's "On Error Goto Next" mode works - and it's pretty much universally considered a bad way to go.
Yet another way to go is to have a 'default' value. For example, the atoi() function, which has pretty much the same functionality that your intval() function, will return 0 when it is unable to convert any characters (it's different from your function in that it consumes characters to convert until it reaches the end of string or a character that is not a digit).
The obvious drawback here is that it can be tricky to tell if an actual value has been converted or if junk has been passed to atoi().
I'm not a huge fan of this way to handle errors.
I'll update as other options cross my mind...
Well, the way that .NET handles this in Int32.TryParse is to return the success/failure, and pass the parsed value back with a pass-by-reference parameter. The same could be applied in C:
int intval(const char *string, s32 *parsed)
{
*parsed = 0; // So that if we return an error, the value is well-defined
// Normal code, returning error codes if necessary
// ...
*parsed = num;
return SUCCESS; // Or whatever
}
a common way is to pass a pointer to a success flag like this:
int my_function(int *ok) {
/* whatever */
if(ok) {
*ok = success;
}
return ret_val;
}
call it like this:
int ok;
int ret = my_function(&ok);
if(ok) {
/* use ret safely here */
}
EDIT: example implementation here:
s32 intval(const char *string, int *ok) {
bool negative = false;
u32 current_char = 0;
if (string[0] == '-') {
negative = true;
current_char = 1;
}
s32 num = 0;
while (string[current_char]) {
if (string[current_char] < '0' || string[current_char] > '9') {
// Return an error here.. but how?
if(ok) { *ok = 0; }
}
num *= 10;
num += string[current_char] - '0';
current_char++;
}
if (negative) {
num = -num;
}
if(ok) { *ok = 1; }
return num;
}
int ok;
s32 val = intval("123a", &ok);
if(ok) {
printf("conversion successful\n");
}
The os-style global errno variable is also popular. Use errno.h.
If errno is non-zero, something went wrong.
Here's a man page reference for errno.
Take a look at how the standard library deals with this problem:
long strtol(const char * restrict str, char **restrict endptr, int base);
Here, after the call the endptr points at the first character that could not be parsed. If endptr == str, then no characters were converted, and this is a problem.
In general I prefer the way Jon Skeet proposed, ie. returning a bool (int or uint) about success and storing the result in a passed address. But your function is very similar to strtol, so I think it is a good idea to use the same (or similar) API for your function. If you give it a similar name like my_strtos32, this makes it easy to understand what the function does without any reading of the documentation.
EDIT: Since your function is explicitly 10-based, my_strtos32_base10 is a better name. As long as your function is not a bottle-neck you can then, skip your implementation. And simply wrap around strtol:
s32
my_strtos32_base10(const char *nptr, char **endptr)
{
long ret;
ret = strtol(nptr, endptr, 10);
return ret;
}
If you later realize it as an bottleneck you can still optimize it for your needs.
You can either return an instance of a class where a property would be the value interested in, another property would be a status flag of some sort. Or, pass in an instance of the result class..
Pseudo code
MyErrStatEnum = (myUndefined, myOK, myNegativeVal, myWhatever)
ResultClass
Value:Integer;
ErrorStatus:MyErrStatEnum
Example 1:
result := yourMethod(inputString)
if Result.ErrorStatus = myOK then
use Result.Value
else
do something with Result.ErrorStatus
free result
Example 2
create result
yourMethod(inputString, result)
if Result.ErrorStatus = myOK then
use Result.Value
else
do something with Result.ErrorStatus
free result
The benefit of this approach is you can expand the info coming back at any time by adding additional properties to the Result class.
To expand this concept further, it also applies to method calls with multiple input parameters. For example, instead of CallYourMethod(val1, val2, val3, bool1, bool2, string1) instead, have a class with properties matching val1,val2,val3,bool1,bool2,string1 and use that as a single input parameter. It cleans up the method calls and makes the code more easily modified in the future. I'm sure you've seen that method calls with more than a few parameters is much more difficult to use/debug. (7 is the absolute most I would say.)
What is the best way to return an error from a function when I'm already returning a value?
Some additional thoughts to the various answers.
Return a structure
Code can return a value and an error code. A concern is the proliferation of types.
typedef struct {
int value;
int error;
} int_error;
int_error intval(const char *string);
...
int_error = intval(some_string);
if (int_error.error) {
Process_Error();
}
int only_care_about_value = intval(some_string).value;
int only_care_about_error = intval(some_string).error;
Not-a-number and NULL
Use a special value when the function return type provides it.
Not-a-number's are not required by C, but ubiquitous.
#include <math.h>
#include <stddef.h>
double y = foo(x);
if (isnan(y)) {
Process_Error();
}
void *ptr = bar(x);
if (ptr == NULL) {
Process_Error();
}
_Generic/Function Overloading
Considering the pros & cons of error_t foo(&dest, x) vs. dest_t foo(x, &error),
With a cascaded use of _Generic or function overloading as a compiler extension, selecting on 2 or more types, it makes sense to differentiate the underlying function called to be based on the parameters of the call, not the return value. Return the common type, the error status.
Example: a function error_t narrow(destination_t *, source_t) that converted the value of one type to a narrower type, like long long to short and tested if the source value was in range of the target type.
long long ll = ...;
int i;
char ch;
error = narrow(&i, ll);
...
error = narrow(&ch, i);

Resources