'How can sem_open() accept different argument sizes if function overloading isn't supported in C?
While learning about shared process semaphores, I noticed that sem_open() features two function prototypes: https://man7.org/linux/man-pages/man3/sem_open.3.html
sem_t *sem_open(const char *name, int oflag);
sem_t *sem_open(const char *name, int oflag, mode_t mode, unsigned int value);
How is this possible if function overloading isn't supported by C?
Solution 1:[1]
The key is found in the manpage (which you linked):
If
O_CREATis specified inoflag, then two additional arguments must be supplied.
That's exactly the way variadic functions work in C. A variadic function has a fixed number of parameters, each with a well-defined type, and then a ..., which can be any number of arguments of any type, with the proviso that the called function has to be able to figure out the type of each argument in order to reference it. printf is indeed the clearest example: the format string includes enough information for printf to know exactly how many and what type of arguments to expect.
Note that guessing is not permitted. If the function asks for an argument which wasn't provided or asks for a different type than the provided argument, it doesn't get a friendly error indication or a second chance. The result is Undefined Behaviour: anything can happen, including abrupt termination or a nonsensical result. Or a result which seems to make sense but has no basis in reality.
Like open, sem_open uses this to allow arguments which are only needed in certain well-defined circumstances. If it is possible that the call will create a new semaphore (or file, in the case of open), it will request the additional arguments, assuming that they are of the types specified in the documentation.
The caller is responsible for ensuring that the call is correct. Note that since variadic arguments do not have a declared type, the compiler cannot insert type conversions. So if the function is expecting a double, it cannot be called with an int, which would normally be possible. Also, if a variadic argument is supposed to be void*, it must be void*, and not, for example, 0 (or NULL), because the automatic conversion from 0 to a null pointer can't be done.
However, the caller is allowed to provide too many arguments, or conversely the called function is not required to examine every argument supplied. (It can't skip over arguments, but it doesn't need to get to the end of the list.)
In retrospect, this may seem like a terrible language feature. But it seemed like a good idea at the time, and it's not going away now.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
