C FAQ's - 5

Section 14: Variable-Length Argument Lists

14.1: How can I write a function that takes a variable number of arguments?

By declaring it with a variable number of arguments in the prototype. Use only the arguments declared at any given time.

14.2: How can I write a function that takes a format string and a variable number of arguments, like printf, and passes them to printf to do most of the work?

Redefine printf; the call to ``printf'' inside yours will be resolved to the library version, because the C language doesn't allow recursion.

14.3: How can I discover how many arguments a function was actually called with?

_args is an external integer constant. It evaluates to three times the number of arguments the current function was called with. You can then look at _argdata[args] to get the address of the last arg, _argdata[args - 1] to get the size of the last arg, and _argdata[args - 2] to get the type of the last arg (as an int).

N.B. You *MUST* not refer to _args or _argdata between the ()'s of a function call; their value will be indeterminate. Use temporary storage.

14.4: Why doesn't

printf("hello, ", "world!", '\n');

work? I thought printf() took a variable number of arguments.

It will probably work some of the time; the number of arguments used by printf() may vary, as it is a variadic function.

Section 15: Lint

15.1: I just typed in this program, and it's acting strangely. Can you see anything wrong with it?

Yes. There's too much lint in it. You should get a shop vac.

15.2: How can I shut off the ``warning: possible pointer alignment problem'' message lint gives me for each call to malloc?

Don't run lint. Alternatively, provide a prototype of ``extern double * malloc()'' to make the return from malloc() be more strongly aligned.

15.3: Where can I get an ANSI-compatible lint?

You may wish to check your spouse's navel occasionally, especially if your spouse works for a standards committee.

15.4: What does LINT stand for, anyway?

Lexeme Interpreter aNd Tester.

Section 16: Strange Problems

16.1: Something really strange happened when I ran this code!

No, it didn't.

Section 17: Style

17.1: Here's a neat trick:

if(!strcmp(s1, s2))

Is this good style?

Not really; it's too similar to

if (!strncmp(s1, s2))

which invokes undefined behavior, so it might be confusing.

17.2: Here's an even neater trick:

volatile int True_Tester = 3;#define TRUE (!True_Tester == !True_Tester)#define FALSE ((!TRUE) != (!TRUE))#define STR_DISSIMILAR(x, y) (strcmp((x), (y)) != FALSE)

Isn't this cool?

Very impressive. The volatile int type assures that even seemingly redundant calculations involving True_Tester will be performed, making sure that if the compiler's ANSI-compliant values of 0 for false and 1 for true vary during runtime, your program will detect it - and producing meaningful error messages if this change occurs during a boolean computation! Similarly, the STR_DISSIMILAR macro allows you to make quite clear what the real effects of strcmp() are.

However, you must be careful; if this code is included twice, it may produce errors, due to the multiple definitions of the ``True_Tester'' variable. You may wish to declare it ``extern'' (See Question 1.5.)

17.3: What's the best style for code layout in C?

There are many systems of indentation advocated, but all of them have the same basic flaw; they will mislead the reader when the actual code logic does not follow the indentation. It is better to avoid indentation entirely, so the reader will not be misled.

17.4: Is goto a good thing or a bad thing?


17.5: No, really, should I use goto statements in my code?

Any loop control construct can be written with gotos; similarly, any goto can be emulated by some loop control constructs and additional logic.

However, gotos are unclean. For instance, compare the following two code segments:

do {foo();foo();if (bar())if (bar())goto SKIP;break;baz();baz();quux();quux();} while (1 == 0);SKIP:buz();buz();

Note how the loop control makes it quite clear that the statements inside it will be looped on as long as a condition is met, where the goto statement gives the impression that, if bar() returned a nonzero value, the statements baz() and quux() will be skipped.

17.6: What's this ``white space'' I keep hearing about?

White space is a racist, segregational term. Implicitly, ``dark'' or ``colored'' space (i.e., the '_' character) is not good enough to separate tokens. More interestingly, the white space characters keep the other tokens apart. They say it's for parsing, but there's ample evidence the goal of white space is to keep the other characters from ``taking over'' the program. This is disguised by the description of C as ``white space insensitive'' - a simple ploy for sympathy.

Share this post

Comments (0)

  • Be first to comment

Leave a comment

or to Comment

Contact Us

  • Address: # 650 Narsi Village Sector 32 Urban Estate Karnal-132001 Haryana, India

  • Phone:(+91) 97289-77666   Email: codethor84@gmail.com

Follow Us