3

I am currently developing a function in C to find the last char occurrence of a given string. I want it to use a certain method (my own) if the length of the string is not given, otherwise it will just use strrchr. So after a bit of researching I decided that a macro would be the way to go. This is what I have:

 size_t strlchr(const char *str, const char ch, const int strln)
 {
    //function code if strlen == -1 (no parameter)
    //function code if strlen != -1 (parameter given)
 }

#define strlchr_arg2(str, ch) strlchr(str, ch, -1)
#define strlchr_arg3(str, ch, strlen) strlchr(str, ch, strln)
#define getarg4(arg2, arg3, arg4...) arg4
#define strlchr_macro(...) \ getarg4(__VA_ARGS__, strlchr(arg3, \ arg2, )
#define strlchr(...) strlchr_macro(__VA_ARGS__)(__VA_ARGS__)

Is this the correct way of acheiving my goal? Or are there any more efficent ways? Also do I have to have the function code before the macro in the source file? I normally write my functions at the bottom, and have my declarations, in this case size_t strlchr(const char*, const char, const int) towards the top of my source file, and finally my macros and such at the top of my source file. So ideally my layout would be:

macros/defines
function declaration
function code

This question is based completely off of other examples I saw from the web. Is this how one would go about using optional function parameters? Or am I way off? I haven't implemented it yet since I would first like to get some input before doing something horribly wrong (I have never made a macro before and this macro is for the most part taken from an example and I have minimal understanding of what it exactly does).

Tim Pierce
  • 5,514
  • 1
  • 15
  • 31
Keith Miller
  • 1,337
  • 1
  • 16
  • 32
  • Updated my question @Kingsindian sorry about that. – Keith Miller Aug 29 '12 at 15:26
  • 1
    @KingsIndian, the parameter would shadow the declaration. If you don't need to use `strlen` inside `strlchr`, then there is no problem with having that name as parameter. I wouldn't use it myself, though. – Shahbaz Aug 29 '12 at 15:27
  • 1
    @keithmiller, what is your ultimate goal? Do you want C to be able to call different functions based on whether 2 or 3 arguments are given? i.e. do you want function overloading as there is in C++? As far as I know, this is impossible. – Shahbaz Aug 29 '12 at 15:28
  • That `was` my ultimate goal, in retrospect I think it would be more logical to just manually put "-1" myself if I don't have the length of the string. – Keith Miller Aug 29 '12 at 15:29
  • 2
    I believe that's your only option. You could also try defining -1 with a name so you use that name, instead of the magic and hard-to-understand by others "-1". – Shahbaz Aug 29 '12 at 15:31
  • 1
    or use a wrapper function. also, some crazy solutions here: http://stackoverflow.com/questions/1472138/c-default-arguments – Karoly Horvath Aug 29 '12 at 15:34

1 Answers1

4

It seems like it would be simpler to do:

size_t strlchr(const char *str, const char ch, const int strln)
{
    //function code if strlen == -1 (no parameter)
    //function code if strlen != -1 (parameter given)
}


#define strlchr_macro(STR, CH, STRLN, ...) strlchr(STR, CH, STRLN)
#define strlchr(...) strlchr_macro(__VA_ARGS__, -1, -1)

this makes both the ch and strln arguments optional, defaulting to -1 if not provided. It also allows you to provide more than 3 arguments (the extra will be ignored), which may be undesirable but probably not a show-stopper.

Chris Dodd
  • 119,907
  • 13
  • 134
  • 226
  • This is nice, but I just realized it has a problem. What if you wanted `ch` to default to `0` and `strlen` to `-1`? Writing `strlchr_macro(__VA_ARGS__, 0, -1)` wouldn't work as you'd expect it. – Shahbaz Sep 05 '12 at 12:14