Function format in a C program - c

I'm writing some functions that manipulate strings in C and return extracts from the string.
What are your thoughts on good styles for returning values from the functions.
Referring to Steve McConnell's Code Complete (section 5.8 in 1993 edition) he suggests I use
the following format:
void my_function ( char *p_in_string, char *p_out_string, int *status )
The alternatives I'm considering are:
Return the result of the function (option 2) using:
char* my_function ( char *p_in_string, int *status )
Return the status of the function (option 3) using:
int my_function ( char *p_in_string, char *p_out_string )
In option 2 above I would be returning the address of a local variable from my_function but my calling function would be using the value immediately so I consider this to be OK and assume the memory location has not been reused (correct me on this if I'm wrong).
Is this down to personal style and preference or should I be considering other issues ?

Option 3 is pretty much the unspoken(?) industry standard. If a IO-based C function that returns an integer, returns a non-zero integer value, it almost always means that the IO operation failed. You might want to refer to this Wikibook's section on return values in C/C++.
The reason that people use 0 for success is because there is only one condition of success. Then if it returns non-zero, you look up somehow what the non-zero value means in terms of errors. Perhaps a 1 means it couldn't allocate memory, 2 means the argument was invalid, 3 means there was some kind of IO error, for instance. Technically, typically you wouldn't return 1, but you'd return XXX_ERR_COULD_NOT_MALLOC or something like that.
Also, never return addresses of local variables. Unless you personally malloced it, there are no guarantees about that variable's address after you return from the function. Read the link for more info.

In option 2 above I would be returning
the address of a local variable from
my_function but my calling function
would be using the value immediately
so I consider this to be OK and assume
the memory location has not been
reused (correct me on this if I'm
wrong).
I'm sorry but you're wrong, go with Steve McConnell's method, or the last method (by the way on the first method, "int status" should be "int* status".
You're forgiven for thinking you'd be right, and it could work for the first 99,999 times you run the program, but the 100,000th time is the kicker. In a multi-threaded or even on multi process architecture you can't rely that someone or something hasn't taken that segment of memory and used it before you get to it.
Better to be safe than sorry.

The second option is problematic because you have to get memory for the result string, so you either use a static buffer (which possibly causes several problems) or you allocate memory, which in turn can easily cause memory leaks since the calling function has the responsibility to free it after use, something that is easily forgotten.
There is also option 4,
char* my_function ( char *p_in_string, char* p_out_string )
which simply returns p_out_string for convenience.

a safer way would be:
int my_function(const char* p_in_string, char* p_out_string, unsigned int max_out_length);
the function would return status, so that it's check-able immediately like in
if( my_function(....) )
and the caller would allocate the memory for the output, because
the caller will have to free it and it's best done at the same level
the caller will know how it handles memory allocation in general, not the function

void my_function ( char *p_in_string, char *p_out_string, int *status )
char* my_function ( char *p_in_string, int *status )
int my_function ( char *p_in_string, char *p_out_string )
In all cases, the input string should be const, unless my_function is explicitly being given permission to write - for example - temporary terminating zero's or markers into the input string.
The second form is only valid if my_function calls "malloc" or some variant to allocate the buffer. Its not safe in any c/c++ implementation to return pointers to local / stack scoped variables. Of course, when my_function calls malloc itself, there is a question of how the allocated buffer is free'd.
In some cases, the caller is given the responsibility for releasing the buffer - by calling free(), or, to allow different layers to use different allocators, via a my_free_buffer(void*) that you publish. A further frequent pattern is to return a pointer to a static buffer maintained by my_function - with the proviso that the caller should not expect the buffer to remain valid after the next call to my_function.
In all the cases where a pointer to an output buffer is passed in, it should be paired with the size of the buffer.
The form I most prefer is
int my_function(char const* pInput, char* pOutput,int cchOutput);
This returns 0 on failure, or the number of characters copied into pOutput on success with cchOutput being the size of pOutput to prevent my_function overruning the pOutput buffer. If pOutput is NULL, then it returns the number of characters that pOutput needs to be exactly. Including the space for a null terminator of course.
// This is one easy way to call my_function if you know the output is <1024 characters
char szFixed[1024];
int cch1 = my_function(pInput,szFixed,sizeof(szFixed)/sizeof(char));
// Otherwise you can call it like this in two passes to find out how much to alloc
int cch2 = my_function(pInput,NULL,0);
char* pBuf = malloc(cch2);
my_function(pInput,pBuf,cch2);

2nd Style:
Don't assume that memory will not be used. There can be threads that may eat up that memory and you are left with nothing but never-ending garbage.

I prefer option 3. This is so I can do error checking for the function inline, i.e. in if statements. Also, it gives me the scope to add an additional parameter for string length, should that be needed.
int my_function(char *p_in_string, char **p_out_string, int *p_out_string_len)

Regarding your option 2:
If you return a pointer to a local variable, that has been allocated on the stack, the behavior is undefined.
If you return a pointer some piece of memory you allocated yourself (malloc, calloc, ...), this would be safe (but ugly, as you might forget free()).
I vote for option 3:
It allows you to manage memory outside of my_function(...) and you can also return some status code.

I would say option 3 is the best to avoid memory management issues. You can also do error checking using the status integer.

There's also a point to consider if your function is time critical. On most architecture, it's faster to use the return value, than to use the reference pointer.
I had the case when using the function return value I could avoid memory accesses in an inner loop, but using the parameter pointer, the value was always written out to memory (the compiler doesn't know if the value will be accessed via another pointer somewhere else).
With some compiler you can even apply attributes to the return value, that can't be expressed on pointers.
With a function like strlen, for instance, some compiler know that between to calls of strlen, if the pointer wasn't changed, that the same value will be returned and thus avoid to recall the function.
In Gnu-C you can give the attribute pure or even const to the return value (when appropriate), thing which is impossible with a reference parameter.

Related

A C function that returns a char array Vs a function working with 2 char arrays

I'm a C beginner so my apologies if this doubt is too obvious.
What would be considered the most efficient way to solve this problem: Imagine that you have a char array ORIG and after working with it, you should have a new char array DEST. So, if I wanted to create a function for this goal, what would the best approach be:
A function that takes only one char array parameter ( argument ORIG ) and returning a char array DEST or
A void function that takes two char array arguments and does its job changing DEST as wished?
Thanks!
This very much depends on the nature of your function.
In your first case, the function has to allocate storage for the result (or return a pointer to some static object, but this wouldn't be thread-safe). This can be the right thing to do, e.g. for a function that duplicates a string, like POSIX' strdup(). This also means the caller must use free() on the result when it is no longer needed.
The second case requires the caller to provide the storage. This is often the idiomatic way to do these things in C, because in this case, the caller could just write
char result[256];
func(result, "bla bla");
and therefore use an automatic object to hold the result. It also has the benefit that you can use the actual return value to signal errors.
Both are ways of valid ways of doing it, but I'd suggest using the latter, since it means you can load the contents into any block of memory, while a returned array will have to be on heap, and be freed by design.
Again, both are valid ways of doing things, and this is just a guideline. What should be done usually depends on the situation.
It depends,
If you know that the length of DEST will be the same as the lenght of ORIG i would go for the 2nd approach because then you wont have to dynamiclly allocate memory for dest inside the function (and remember to free it outside the function).
If the length is different you have to dynamiclly allocate memory and you can do so in two ways:
1. Like your first approach - for returning array from a function in c you have to allocate a new array and return it's address(pointer)
2. The function can recieve two argument one is ORIG and second is a double pointer to RES , because the function recieves a double pointer it can allocate an array inside and return it via the argument.
1- is more "cleaner" way in terms of code ,and easier to use in terms of user expirience(the user is the caller)
Good luck!
In option 1 you will have to dynamically allocate (malloc) the output array. Which means you have a potential for a memory leak. In option 2 the output array is provided for you, so there is no chance of a leak, but there is a chance that the output array is not of sufficient size and you will get a buffer overrun when writing to it.
Both methods are acceptable, there might be a small performance difference in one compared to the other, but its really down to your choice.
Personally, being a cautios programmer, I would go for option 3:
/* Returns 0 on success, 1 on failure
Requires : inputSize <= outpuSize
input != output
input != null
output != null
*/
int DoStuff (char* output, size_t outputSize, char* input, size_t inputSize);
(Sorry if that's not proper C, its been decades:) )
(Edited in accordance with Felix Palmen's points.)

Return a string allocated with malloc?

I'm creating a function that returns a string. The size of the string is known at runtime, so I'm planning to use malloc(), but I don't want to give the user the responsibility for calling free() after using my function's return value.
How can this be achieved? How do other functions that return strings (char *) work (such as getcwd(), _getcwd(), GetLastError(), SDL_GetError())?
Your challenge is that something needs to release the resources (i.e. cause the free() to happen).
Normally, the caller frees the allocated memory either by calling free() directly (see how strdup users work for instance), or by calling a function you provide the wraps free. You might, for instance, require callers to call a foo_destroy function. As another poster points out you might choose to wrap that in an opaque struct, though that's not necessary as having your own allocation and destroy functions is useful even without that (e.g. for resource tracking).
However, another way would be to use some form of clean-up function. For instance, when the string is allocated, you could attach it to a list of resources allocated in a pool, then simply free the pool when done. This is how apache2 works with its apr_pool structure. In general, you don't free() anything specifically under that model. See here and (easier to read) here.
What you can't do in C (as there is no reference counting of malloc()d structures) is directly determine when the last 'reference' to an object goes out of scope and free it then. That's because you don't have references, you have pointers.
Lastly, you asked how existing functions return char * variables:
Some (like strdup, get_current_dir_name and getcwd under some circumstances) expect the caller to free.
Some (like strerror_r and getcwd in under other circumstances) expect the caller to pass in a buffer of sufficient size.
Some do both: from the getcwd man page:
As an extension to the POSIX.1-2001 standard, Linux (libc4, libc5, glibc) getcwd() allocates the buffer dynamically
using malloc(3) if buf is NULL. In this case, the allocated buffer has the length size unless size is zero, when
buf is allocated as big as necessary. The caller should free(3) the returned buffer.
Some use an internal static buffer and are thus not reentrant / threadsafe (yuck - do not do this). See strerror and why strerror_r was invented.
Some only return pointers to constants (so reentrancy is fine), and no free is required.
Some (like libxml) require you to use a separate free function (xmlFree() in this case)
Some (like apr_palloc) rely on the pool technique above.
Many libraries force the user to deal with memory allocation. This is a good idea because every application has its own patterns of object lifetime and reuse. It's good for the library to make as few assumptions about its users as possible.
Say a user wants to call your library function like this:
for (a lot of iterations)
{
params = get_totally_different_params();
char *str = your_function(params);
do_something(str);
// now we're done with this str forever
}
If your libary mallocs the string every time, it is wasting a lot of effort calling malloc, and possibly showing poor cache behavior if malloc picks a different block each time.
Depending on the specifics of your library, you might do something like this:
int output_size(/*params*/);
void func(/*params*/, char *destination);
where destination is required to be at least output_size(params) size, or you could do something like the socket recv API:
int func(/*params*/, char *destination, int destination_size);
where the return value is:
< desination_size: this is the number of bytes we actually used
== destination_size: there may be more bytes waiting to output
These patterns both perform well when called repeatedly, because the caller can reuse the same block of memory over and over without any allocations at all.
There is no way to do this in C. You have to either pass a parameter with size information, so that malloc() and free() can be called in the called function, or the calling function has to call free after malloc().
Many object oriented languages (eg. C++) handle memory in such a way as to do what you want to, but not C.
Edit
By size information as an argument, I mean something to let the called function know the how many bytes of memory are owned by the pointer you are passing. This can be done by looking directly at the called string if it has already been assigned a value, such as:
char test1[]="this is a test";
char *test2="this is a test";
when called like this:
readString(test1); // (or test2)
char * readString(char *abc)
{
int len = strlen(abc);
return abc;
}
Both of those arguments will result in len = 14
However if you create a non populated variable, such as:
char *test3;
And allocate the same amount of memory, but do not populate it, for example:
test3 = malloc(strlen("this is a test") +1);
There is no way for the called function to know what memory has been allocated. The variable len will == 0 inside the 1st prototype of readString(). However, if you change the prototype readString() to:
readString(char *abc, int sizeString); Then size information as an argument can be used to create memory:
void readString(char *abc, size_t sizeString)
{
char *in;
in = malloc(sizeString +1);
//do something with it
//then free it
free(in);
}
example call:
int main()
{
int len;
char *test3;
len = strlen("this is a test") +1; //allow for '\0'
readString(test3, len);
// more code
return 0;
}
You cannot do this in C.
Return a pointer and it is up to the person calling the function to call free
Alternatively use C++. shared_ptr etc
You can wrap it in a opaque struct.
Give the user access to pointers to your struct but not its internal. Create a function to release resources.
void release_resources(struct opaque *ptr);
Of course the user needs to call the function.
You could keep track of the allocated strings and free them in an atexit routine (http://www.tutorialspoint.com/c_standard_library/c_function_atexit.htm). In the following, I have used a global variable but it could be a simple array or list if you have one handy.
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
char* freeme = NULL;
void AStringRelease(void)
{
if (freeme != NULL)
free(freeme);
}
char* AStringGet(void)
{
freeme = malloc(20);
strcpy(result, "A String");
atexit(AStringRelease);
return freeme;
}

Getting return value from a function in C

consider the the two functions :
int add1(int x,int y)
{
return x+y;
}
void add2(int x,int y,int *sum)
{
*sum=x+y;
}
I generally use functions of the form add1 but I found some codes using functions of the form add2.
Even if the size return value is large(like an array or struct) we can just return its ponter
I wonder if there any reason for using the second form?
There's also the reason of returning success state.
There are a lot of functions like:
bool f(int arg1, int arg2, int *ret)
{
}
Where bool (or enum) return the success of the function. Instead of checking if ret is null... (And if you had more than 1 variable).
If you want to return two values from your function, then C is helpless unless you use pointers just like your function add2.
void add2()
{
/* Some Code */
*ptr1=Something;
*ptr2=Something;
}
Form 2 is very common for "multiple returns" in C. A canonical example is returning the address to a buffer and the length of the buffer:
/* Returns a buffer based on param. Returns -1 on failure, or 0 on success.
Buffer is returned in buf and buflen. */
int get_buffer(void *param, char **buf, int *buflen);
Functions of the form 2 are not faster than functions of the form 1 when you're using things as small as int. In fact, in this case, the second one is slower because you have to dereference the passed pointer. It's only useful in this case if your aim was to pass in an array of values)
Always use functions of the form 1 unless you want to pass in a very large piece of data to the function. In that case, the form 2 would be faster.
The reason we use the second form is because for large objects, we want to avoid copying them. Instead of copying them, we could just pass their memory addresses to the function. This is where the pointer comes in. So instead of giving the function all the data, you would just tell it where this data. (I hope this analogy is good enough)
It is largely a matter of preference and local conventions. The second form might be used alongside a bunch of other similar functions where the third parameter in each of them is always passed as a pointer to a return value.
Personally, I like the first form for almost all purposes: it does not require a pointer to be passed, and it allows some type flexibility in handling the return value.
Returning a value by writing to memory passed via a pointer is reasonable, when the returned object is large, or when the return value of the function is used for other purposes (e.g. signaling error conditions). In the code you have shown, neither of these two is the case, so I'd go for the first implementation.
When you return a pointer from a function, you have to make sure that the pointed to memory is valid after the function call. This means, the pointer must point to the heap, making an allocation on the heap necessary. This puts a burdon on the caller; he has to deallocate memory that he did not explicitly allocate.

C char* pointers pointing to same location where they definitely shouldn't

I'm trying to write a simple C program on Ubuntu using Eclipse CDT (yes, I'm more comfortable with an IDE and I'm used to Eclipse from Java development), and I'm stuck with something weird. On one part of my code, I initialize a char array in a function, and it is by default pointing to the same location with one of the inputs, which has nothing to do with that char array. Here is my code:
char* subdir(const char input[], const char dir[]){
[*] int totallen = strlen(input) + strlen(dir) + 2;
char retval[totallen];
strcpy(retval, input);
strcat(retval, dir);
...}
Ok at the part I've marked with [*], there is a checkpoint. Even at that breakpoint, when I check y locals, I see that retval is pointing to the same address with my argument input. It not even possible as input comes from another function and retval is created in this function. Is is me being unexperienced with C and missing something, or is there a bug somewhere with the C compiler?
It seems so obvious to me that they should't point to the same (and a valid, of course, they aren't NULL) location. When the code goes on, it literally messes up everything; I get random characters and shapes in console and the program crashes.
I don't think it makes sense to check the address of retval BEFORE it appears, it being a VLA and all (by definition the compiler and the debugger don't know much about it, it's generated at runtime on the stack).
Try checking its address after its point of definition.
EDIT
I just read the "I get random characters and shapes in console". It's obvious now that you are returning the VLA and expecting things to work.
A VLA is only valid inside the block where it was defined. Using it outside is undefined behavior and thus very dangerous. Even if the size were constant, it still wouldn't be valid to return it from the function. In this case you most definitely want to malloc the memory.
What cnicutar said.
I hate people who do this, so I hate me ... but ... Arrays of non-const size are a C99 extension and not supported by C++. Of course GCC has extensions to make it happen.
Under the covers you are essentially doing an _alloca, so your odds of blowing out the stack are proportional to who has access to abuse the function.
Finally, I hope it doesn't actually get returned, because that would be returning a pointer to a stack allocated array, which would be your real problem since that array is gone as of the point of return.
In C++ you would typically use a string class.
In C you would either pass a pointer and length in as parameters, or a pointer to a pointer (or return a pointer) and specify the calls should call free() on it when done. These solutions all suck because they are error prone to leaks or truncation or overflow. :/
Well, your fundamental problem is that you are returning a pointer to the stack allocated VLA. You can't do that. Pointers to local variables are only valid inside the scope of the function that declares them. Your code results in Undefined Behaviour.
At least I am assuming that somewhere in the ..... in the real code is the line return retval.
You'll need to use heap allocation, or pass a suitably sized buffer to the function.
As well as that, you only need +1 rather than +2 in the length calculation - there is only one null-terminator.
Try changing retval to a character pointer and allocating your buffer using malloc().
Pass the two string arguments as, char * or const char *
Rather than returning char *, you should just pass another parameter with a string pointer that you already malloc'd space for.
Return bool or int describing what happened in the function, and use the parameter you passed to store the result.
Lastly don't forget to free the memory since you're having to malloc space for the string on the heap...
//retstr is not a const like the other two
bool subdir(const char *input, const char *dir,char *retstr){
strcpy(retstr, input);
strcat(retstr, dir);
return 1;
}
int main()
{
char h[]="Hello ";
char w[]="World!";
char *greet=(char*)malloc(strlen(h)+strlen(w)+1); //Size of the result plus room for the terminator!
subdir(h,w,greet);
printf("%s",greet);
return 1;
}
This will print: "Hello World!" added together by your function.
Also when you're creating a string on the fly you must malloc. The compiler doesn't know how long the two other strings are going to be, thus using char greet[totallen]; shouldn't work.

How to check for type in C in function

I'm making a function that takes two pointer to strings as arguments.It works fine, as long as you pass it valid arguments.
I wanna know how to check that these pointer are valid and not for example two random ints . How do I do that?
char ** LCS ( char * s1, char * s2) //thats the function
...
LCS(0,0) //...awful crash.. How do I avoid it?
In the body of the function, check:
if ((s1==NULL) || (s2==NULL)) {
/* Do something to indicate bad parameters */
}
With documentation and by following the C motto: "trust the programmer".
/* s1 and s2 must be both valid pointers to null-terminated strings
** otherwise the behaviour is undefined */
char ** LCS ( char * s1, char * s2);
Does it make sense for someone to call your function with NULL arguments? If not, you should disallow NULL arguments in the contract of your function, e.g. by adding a comment above the declaration saying that it only works on valid, non-NULL arguments. In other words, anyone who uses your function agrees not to give NULL arguments; it's then their responsibility to check against this, not yours.
If it does make sense for either or both of the arguments to be NULL, then you need to decide on how your function behaves in that case and implement it thus. In this case you are agreeing to support NULL arguments and do something sensible with them, and therefore it becomes your responsibility to check for this and act accordingly (e.g. if (s1 == NULL)).
If you cannot think of any sensible behaviour for NULL arguments, then go with the first option and disallow them altogether. If you do this, then your example call LCS(0,0); is in breach of contract (i.e. passes NULL pointers when the function does not agree to accept them) and should be removed. In a more complex scenario if you are passing the arguments from variables and there is a chance that those variables point to NULL, then you must check before calling LCS, e.g. if (v1 && v2) { LCS(v1,v2); } else { … }.
To track possible errors relating to this, you could use assert to check, e.g.:
#include <assert.h>
char **LCS (char *s1, char *s2) {
assert(s1);
assert(s2);
…
}
This will cause your program to exit if s1 or s2 is NULL, unless NDEBUG was defined before including assert.h (in which case the assertions do nothing). So the assertions are a way to check, during development, that the caller is not giving you NULL arguments but it's still an error if they do.
As for other invalid pointers, you cannot really even check reliably, e.g. there's no way of knowing whether the caller has a really strange string or if they just passed the wrong address. This, too, is their responsibility to avoid, and LCS should simply assume that the caller is giving you valid data. Of course if you have additional restrictions, e.g. maximum length of the argument strings, then you must make these restrictions clear to the caller (i.e. specify the contract for the function, “this function does X [your responsibility as the implementor of LCS] provided that … [their responsibilities as the user of LCS]”). This applies to all programming, for example the C standard specifies how the language itself and the standard library functions must be used (e.g. cannot divide by zero, argument strings for strcpy cannot overlap, etc).
In C, I'm afraid you have to just be careful and hope the programmers know what to do.
In this case, 0 (zero, null, NULL) is valid input for the function.
Normally is that case, you would at least protect the function by checking if the input is valid.
for example ...
char** LCS (char *s1, char *s2 )
{
if ( s1 == 0 )
return ...;
if ( s2 == 0 )
return ...;
if ( strlen( s1 ) == 0 )
return ...
/// do something ...
}
The best you can do is check against NULL (0). Otherwise, there's no standard way to tell whether a non-NULL pointer value is valid. There may be some platform-specific hacks available, but in general this problem is dealt with by documentation and good memory management hygiene.
You can implement your own type checking using a struct like this. But you could also just use a language with proper type checking. :)
typedef struct Var {
enum Type { int, ptr, float ... } type;
union {
int Int;
void *Ptr;
float Float;
...
} data;
} Var;
The ideology of C revolves around the principle that 'The programmer knows what (s)he is doing.' Half the reason as to why C is so lightweight and speedy, is because it doesn't perform such type checks.
If you really need to perform such checks, you might be better off in C++, using references (which are assured to be non-null) instead of pointers.
First, as everyone else has said:
Check for NULL parameters
Everything else is heuristics and careful programming
You can provide a function prototype to your callers and turn the warnings to 11: (at least -Werror -Wall and -Wextra for gcc). This will cause a compilation error if a parameter of an improper type is passed in. It doesn't help if the caller first casts his parameters to char *s (e.g. LCS((char*)1, (char*)1 )
You could call strlen on your arguments, but if the values are non-NULL but still illegal values, the strlen could crash.
You could attempt to see if the pointers are in valid segments for the program. This is not portable, and still not foolproof.
So, to summarize, check for NULL, and turn the warnings to 11. This is what's done in practice.
You can't really do this. First, if a programmer passes in arbitrary integers cast as pointers then they may actually be valid pointers within your address space -- they might even point to null terminated character arrays (in fact, if they are within your address space they will point because the data there will be treated as characters and at some point there will be a 0 byte).
You can test for several invalid (for applications, anyway) pointer values, including NULL and maybe even any value that would point to the first page of the processes address space (it is usually not mapped and can safely be assumed not to be valid). On some systems there are other pages that are not ever mapped (like the last page). Some systems also have ways ask about the memory map of a process (/proc/self/maps under Linux) which you could (with a lot of trouble) look at and see if the pointer was within a mapped area with the appropriate access.
If you are using a *nix system something you could do would be to register a signal handler for SIGSEGV which gets raised when your program tries to access memory that it shouldn't be accessing. Then you could catch that and with some work figure out what has happened. Another thing you could do would be to call a system call that takes a pointer and use the pointers you have been passed as arguments and see if it fails (with errno == EFAULT). This is probably not good since system calls do things besides just testing memory for read and/or write permissions. You could always write the first byte pointed to by a pointer to /dev/null or /dev/zero (using the write system call, not stdio functions) to determine if you have read permissions, but if you read a byte from /dev/zero or /dev/random into the first byte pointed to (using the read system calls, not stdio functions), but if the data at that area is important then you would have over written a byte of it. If you were to have tried to save a copy of that data into a local variable so that you could restore it after the test then you might have caused an error when you read from it within your program. You could get elaborate and write it out and then read it back in to test both access rights, though, but this is getting complicated.
Your best bet is to just rely on the user of your function to do the right thing.

Resources