Is it possible to provide default values to function arguments in C? For example:
void display(int a, int b = 10) {
// do something
}
main() {
display(1);
display(1,2); // override default value
}
Visual Studio 2008, complains that there is a syntax error in void display(int a, int b = 10). If this is not legal in C, what is the alternative?
-
2Indeed it is not legal in C. C also doesn't have overloading.Mysticial– Mysticial2012年02月07日 23:09:42 +00:00Commented Feb 7, 2012 at 23:09
-
1Possible duplicate: stackoverflow.com/questions/1472138/c-default-argumentsTimothy Jones– Timothy Jones2012年02月07日 23:11:27 +00:00Commented Feb 7, 2012 at 23:11
-
stackoverflow.com/questions/2988038/…user900360– user9003602014年04月23日 05:52:53 +00:00Commented Apr 23, 2014 at 5:52
-
Possible duplicate of Default values on arguments in C functions and function overloading in CJonathan Mee– Jonathan Mee2018年04月06日 13:53:17 +00:00Commented Apr 6, 2018 at 13:53
6 Answers 6
Default parameters is a C++ feature.
C has no default parameters.
Comments
It is not possible in standard C. One alternative is to encode the parameters into the function name, like e.g.
void display(int a){
display_with_b(a, 10);
}
void display_with_b(int a, int b){
//do something
}
1 Comment
There are no default parameters in C.
One way you can get by this is to pass in NULL pointers and then set the values to the default if NULL is passed. This is dangerous though so I wouldn't recommend it unless you really need default parameters.
Example
function ( char *path)
{
FILE *outHandle;
if (path==NULL){
outHandle=fopen("DummyFile","w");
}else
{
outHandle=fopen(path,"w");
}
}
Comments
If you are using a compiler compatible with C++2a, then there is a preprocessor trick that you can use, as explained at https://stackoverflow.com/a/10841376/18166707
You can use this code snippet as an example:
#include <stdio.h>
#define ADD_THREE(a,b,...) add_three_nums(a, b, (0, ##__VA_ARGS__))
int add_three_nums( int a, int b, int c)
{
return a + b + c;
}
void main( void )
{
printf("%d\n", ADD_THREE(3, 5));
printf("%d\n", ADD_THREE(4, 6, 8));
}
Comments
Not that way...
You could use an int array or a varargs and fill in missing data within your function. You lose compile time checks though.
Comments
From https://stackoverflow.com/a/78487689/2706707
Requires C99, of course. Credits in the code. (I would not likely have figured this out on my own.)
c-default-args.h
#ifndef DUTHOMHAS_C_DEFAULT_ARGUMENTS_H
#define DUTHOMHAS_C_DEFAULT_ARGUMENTS_H
#if !defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L)
#error "Variadic Macros require C99 or better"
#endif
// Copyright 2021 Michael Thomas Greer
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// https://www.boost.org/LICENSE_1_0.txt )
// This is a VERY simple library to provide default argument capabilities to C functions.
// I suppose it is possible to dive very much deeper down the preprocessor rabbit hole
// and make using this really short and pretty, but the cost is enormous and this suffices
// me. Example usage:
//
// #include <duthomhas/c-default-args.h>
//
// int my_function( int a, int b, int c );
// #define my_function(...) DUTHOMHAS_CALL_OVERLOAD(my_function_,__VA_ARGS__)
// #define my_function_0() my_function( -7, 512, 42 )
// #define my_function_1(a) my_function( a, 512, 42 )
// #define my_function_2(a,b) my_function( a, b, 42 )
// #define my_function_3(a,b,c) my_function( a, b, c )
//
// int x = my_function(); // same as: int x = my_function( -7, 512, 42 );
// int y = my_function( 15, 4000 ); // same as: int y = my_function( 15, 4000, 42 );
//
// The equivalent construct in C++ would be:
//
// int my_function( int a=-7, int b=512, int c=42 );
//
// Do not define my_function_N for the argument lists that are not permitted and let the
// compiler complain for you if the user did not provide a correct number of arguments.
//
// #define my_function(...) DUTHOMHAS_CALL_OVERLOAD(my_function_,__VA_ARGS__)
// #define my_function_1(a) my_function( a, M_PI, 74 )
// #define my_function_3(a,b,c) my_function( a, b, c )
//
// int x = my_function(); // compile error
// int y = my_function( 3 ); // OK
// int y = my_function( 3, 5 ); // compile error
// int z = my_function( 3, 5, 7 ); // OK
//
// Not only too few arguments, but too many arguments will lead to compiler error as well.
//
// int q = my_function( 1, 2, 3, 4, 5 ); // compiler error
//
// The compile error will look something like:
//
// "implicit declaration of function 'my_function_0' is invalid"
// "unresolved external symbol my_function_0 referenced in function main"
#ifdef __clang__
#pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
#endif
// Francesco Pretto (ceztko) --> https://stackoverflow.com/a/26685339/2706707
#ifdef _MSC_VER // Microsoft compilers
#define DUTHOMHAS_EXPAND(x) x
#define DUTHOMHAS_NARGS_0(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32, VAL, ...) VAL
#define DUTHOMHAS_NARGS_1(...) DUTHOMHAS_EXPAND(DUTHOMHAS_NARGS_0(__VA_ARGS__,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0))
#define DUTHOMHAS_AUGMENTER(...) unused, __VA_ARGS__
#define DUTHOMHAS_NARGS(...) DUTHOMHAS_NARGS_1(DUTHOMHAS_AUGMENTER(__VA_ARGS__))
#else // Others
#define DUTHOMHAS_NARGS(...) DUTHOMHAS_NARGS_0(0, ## __VA_ARGS__, 32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0)
#define DUTHOMHAS_NARGS_0(_0,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,N,...) N
#endif
// Braden Steffaniak --> https://stackoverflow.com/a/24028231/2706707
#define DUTHOMHAS_GLUE(x, y) x y
#define DUTHOMHAS_OVERLOAD_MACRO2(name, count) name##count
#define DUTHOMHAS_OVERLOAD_MACRO1(name, count) DUTHOMHAS_OVERLOAD_MACRO2(name, count)
#define DUTHOMHAS_OVERLOAD_MACRO(name, count) DUTHOMHAS_OVERLOAD_MACRO1(name, count)
#define DUTHOMHAS_CALL_OVERLOAD(name, ...) DUTHOMHAS_GLUE(DUTHOMHAS_OVERLOAD_MACRO(name, DUTHOMHAS_NARGS(__VA_ARGS__)), (__VA_ARGS__))
#endif