endolith
endolith

Reputation: 26823

Does C support optional null parameters?

In Python, I'm used to things like

def send_command(command, modifier = None):

and then the modifier argument is optional, and the absence of the argument can be differentiated from an argument of 0. Is there similar functionality in C? I'm inexperienced with C, and Googling, but can't find a clear statement of how to use optional parameters in C. It seems you can assign them similarly, like this:

void send_command(uint8_t command, uint8_t modifier = 0) {

so the second argument is optional and defaults to 0 if not used? (Edit: No, this is invalid C anyway)

But can the function distinguish between send_command(SOMETHING) and send_command(SOMETHING, 0)? Ideally, the second parameter could be any uint8 value, including 0.

Maybe NULL is different from 0?

void send_command(uint8_t command, uint8_t modifier = NULL) {

Upvotes: 8

Views: 25155

Answers (6)

Sylvain Chiron
Sylvain Chiron

Reputation: 290

Using a struct

It is possible to have optional arguments in C, and even labeled ones, by using a struct:

typedef struct {
    int a, b, c;
} Options;

void func(Options options);

Then, call func like this (since C99):

func((Options){ 1, 2 });
func((Options){ .c = 3 });

Non-specified values are defaulted to zero.

If you're okay with using a macro, you can write:

#define func(...) func((Options){ __VA_ARGS__ })

so that you can call like this:

func(1, 2);
func(.c = 3);

You can even specify values other than zero (this is incompatible with C++):

struct options {
    char unused;
    int a, b, c;
};

void func(struct options options);
#define func(...) func((struct options){ .a = 1, 2, 3, .unused = 0, __VA_ARGS__ })

Well, this is becoming quite ugly.

Also remember that passing a struct as argument makes your program slower (because the struct is stored in memory while simple values such as ints and pointers are stored in registers), so these struct-solutions should certainly not be used for low-level functions which need performance.

I very often use structs to have optional, defaultly-nulled arguments. I tried to use my ideas of macros but it never seemed to be a good idea.

I don't understand why others didn't think about structs like me in so much time…!

Using a trick with arrays

Let's go on a bit with ugly code. Sometimes I used this trick (works also since C99):

void func(int a, int b, int c);
#define func(a, ...) func(a, (int[2]){ __VA_ARGS__ }[0], (int[2]){ __VA_ARGS__ }[1])

Then you can call func with either 1, 2 or 3 arguments, with b and c defaulting to zero if not specified.

Note that compiler optimizations will get rid of the arrays.

Upvotes: 0

Jens Gustedt
Jens Gustedt

Reputation: 78943

As others said C doesn't support default arguments of functions directly. But there are ways to do this with macros. P99 has convenient "meta"-macros that make this feature relatively easy to specify. As an example to avoid to repeatedly have to specify the second argument of the pthread_mutex_init function:

P99_PROTOTYPE(int, pthread_mutex_init, pthread_mutex_t*, pthread_mutexattr_t const*);
#define pthread_mutex_init(...) P99_CALL_DEFARG(pthread_mutex_init, 2, __VA_ARGS__)
P99_DECLARE_DEFARG(pthread_mutex_init, , (pthread_mutexattr_t*)0);

and straight forward to use afterwards

pthread_mutex_init(&my_mutex);

The semantic of evaluation of the default argument here is the same as for C++, that is the evaluation context of the default argument is the context of the declaration. There is also the possibility to specify this in a way that the context of evaluation is the context of the macro invocation.

Upvotes: 2

R.. GitHub STOP HELPING ICE
R.. GitHub STOP HELPING ICE

Reputation: 215387

Optional parameters are possible in C99 with variadic macros:

#define JUST3(a, b, c, ...) (a), (b), (c)
#define FUNC(...) func(JUST3(__VA_ARGS__, 0, 0))

Now FUNC(x) expands to func((x), (0), (0)), FUNC(x,y) expands to func((x), (y), (0)), etc.

Upvotes: 14

Samuel Edwin Ward
Samuel Edwin Ward

Reputation: 6675

As others have said, C does not have optional parameters.

As for the difference between NULL and 0, there isn't much of one.

Upvotes: 3

Roy Dictus
Roy Dictus

Reputation: 33139

The C Programming Language has no optional parameters. C++ does, but "the mother of many modern programming languages" C does not...

Upvotes: 0

David Heffernan
David Heffernan

Reputation: 613252

C does not support optional parameters. Nor does it support function overloading which can often be used to similar effect.

Upvotes: 19

Related Questions