1

I have function with variable number of arguments, so I want to access them without using int variable as a number of other arguments. I was trying to access arguments using pointer to the first argument. But the result I got isn't the result I expected. You see I have special symbol \0 as an end of arguments. Any clues what to do with that? Or should I rather return to using va_list to access arguments?

#include <stdio.h>

int vowels(char symbol, ...); 

int main() {

printf("%d\n", vowels('a', 'e', 'o', 'i', 'u', '\0'));

printf("%d\n", vowels('d', 'b', 'o', 'c', 'u', '\0'));

return 0;
}
int vowels(char symbol, ...) {
    int counter = 0;
    char *ptr = &symbol;
    while (*ptr != '\0') {

        if (*ptr == 'a' || *ptr == 'e' || *ptr == 'o' || *ptr == 'i' || *ptr == 'u') {
           counter++;
        }

        ptr++;
    }
    return counter;
    }
3
  • You must use <stdarg.h> functions to access variadic functions. Using a pointer will fail, because the way they are passed, through stack or registers, depends on machine ABI (Application Binary Interface). See en.wikipedia.org/wiki/Stdarg.h Commented Nov 21, 2020 at 18:08
  • 1
    Yes: MUST MUST MUST use <stdarg.h> - do not ever try to roll this yourself. Commented Nov 21, 2020 at 18:10
  • OK, I knew about <stdarg.h> , but just had a question, thank you. Commented Nov 21, 2020 at 18:13

2 Answers 2

1

If you want to do it yourself, you need to look at the source code of the C runtime library and see what it does when you access the arguments. Or what the generated inline code does, if the compiler inlines this. Use https://godbolt.org to easily see what code gets generated. This is also a matter of a documented ABI on both ARM and x86-64 targets, so you can read there how the arguments get passed to variadic functions.

In general, by using char* you’re ignoring the ABI-mandated alignment of arguments on the stack. In C++ you’d want char alignas(void*)* in most cases, but even then this sort of manipulation is undefined behavior so you’re writing brittle and unportable code.

When you implement it properly using the standard variadic argument support, your code will be portable among a multitude of architectures, even small 8- and 16-bit microcontrollers. I’ve just checked and the code then works on Zilog’s eZ8 (an 8-bit system with 16-bit far pointers) and on Zilog ZNEO (a 16-bit system with 24-bit pointers and 32-bit integers), and that’s on Zilog’s own C compiler, not gcc. I’ve checked that it works on both hardware and on the simulator in the IDE.

Sign up to request clarification or add additional context in comments.

Comments

1

What you are looking for is a variadic function. You have to #include <stdarg.h> . More info can be found here: GNU Variadic Functions and here

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.