What is the correct return type for a C function that returns different data types

I was once asked to write a function that will return a pointer to some data in memory with some successful state, otherwise it should return "-1". In this case, what will be the correct return type. If I had to return data, then I would have char * as the return type of the myfunction function. But in this case, I can return -1, has a return type.

<what-type> myfunction() { char *data; if (some condition true) return data; else return -1 } int main () { myfunction } 
+4
source share
5 answers

Use union and perhaps define a typedef for it.

i.e.

 typedef struct { int is_error; union { int error_code; char *data; } } ReturnType; 

Then

 ReturnType myFunction(....) { ... etc } 

The caller can check if the function is an error (get a return error code) or get data otherwise.

+7
source

If you want to return different data types, use void* :

 void* myfunction(); ^^^^^ 

In your case, returning NULL seems to be a more ideal solution than -1 .
This will allow users of your function to write code, for example:

 if(myfunction()) { //Utilize the returned string } 
+4
source

which will return a pointer .. with some successful else condition, it should return "-1".

Do yourself a favor and not give an indication of the mixing error and the result of the function on one object like this. Separate them in two different objects, allowing the function to simply return a logical success indicator and return the actual result data, although a pointer seems to be

 bool myfunction(char **result_ptr) { char *data; if (some error condition) return false; *result_ptr = data; return true; } int main () { bool success; char *data: success = myfunction(&data); if (success) use(data); } 

In-band error indicators make a bad API, which often causes failures (in the worst case, the realloc function, it asks you to write code that loses the original pointer in the event of a failure), and it does not work, at least after Characteristics of a good API

  • Ease of use, even without documentation
  • Hard to abuse
  • Easy to read and maintain code that uses it

CERT recommends against them in terms of security.

0
source

You can pour -1 into void * and check it out. you can return ((void *) - 1); Note that the concept of C. there is no concept of pointers in C.

If you think he's a little crazy :-), you're probably right. But there are times when this convention may be useful for error handling. And there is use of it there in important projects. In particular, the pthread library implementation uses this convention at times.

Can a pointer (address) be negative?

There is a lot to say about this.

By the concept of special interpretations of pointers by their meaning.

So there seems to be some problems about how to guarantee that (void *) - 1 is not an actual pointer. and @ictoofay seems to think that somehow I mentioned the guarantee (void *) - 1 above and how it cannot be a valid address, which I would like to clarify that I did not.

Having said that, it is assumed that a system using direct memory mapping, rather than virtual addresses. (void *) - 1 will be the most recent address in this model, and in the strict sense you should not use it. However, you can make assumptions about the storage capacity of the last physical address (see the ldl example below)

But the concept of a β€œspecial” interpretation of pointers by studying value in real projects is not new. In fact, this concept is used in most modern operating systems when they manage a memory address. It is very common that the system will use addresses and address ranges and use them for "special meaning". Therefore, in fact, you, as a programmer, are really free to make any assumptions and live with their consequences. The notion that (void *) - 1 can be used as a special meaning is just around the corner. Note that this still does NOT say anything about (in?) The concept's compatibility with the fact that (void *) - 1 may be a valid address in this case.

Now to solve this "crazy" concept and why someone is using. Here are two real-world examples of where (void *) - 1 is safe.

pthreads uses it on Linux, HPUX, Solaris, and most BSDs.

In particular, PTHREAD_CANCELED is ((void *) - 1)

From pthread.h

#define PTHREAD_CANCELED ((void *) -1)

It is defined as ((void *) 1) in the darwin version of the pthread libraries. Fun fun;

In glibc (with the definition of _GNU_SOURCE), ld.so provides the ability to search for alternative values ​​of the same character in dynamically loaded libraries. The value of RTLD_NEXT is (void *) - 1.

Thought of Flow C

In C there is no reason why this value should be interpreted in a certain way. C is not strongly typed and is fluid in these terms. From this comes a lot of energy.

In the "value" NULL

Could the corresponding C # define NULL implementation be something ridiculous

has a fun explanation of concepts.

-1
source

If you do not use NULL, you can give a return value

 char* myfuntion(){ return (char*)-1; } int main () { printf("%d",myfuntion()); } 
-1
source

Source: https://habr.com/ru/post/1482300/


All Articles