• 12
• 27
• 9
• 9
• 20

# Curious : What is the dreaded elipsis construct?

This topic is 4582 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I've seen some posts with the mention of the "dreaded elipsis construct". What is it, and why is it 'dreaded'? --random [Edited by - random_thinker on August 26, 2005 3:27:00 PM]

##### Share on other sites
It's vararg functions, such as printf, which take an arbitrary number of arguments. And it's dreaded in C++ because it completely discards type-safety in favor of a bizarre, complex, and unintuitive system of type coercion and unsafe getter functions.

##### Share on other sites
The ellipsis construct is used in varidic functions like printf(). You using it like:

int my_function(int some_argument, ...);

And the ellipsis construct sucks up all the parameters after the initial arguments. This is one of the legacies C++ has inherited from C. The down side is that the ellipsis completely destroys type safety. There is no knowledge of type except what the function can guess from the non-ellipsis arguments. This construct does not interact well with pretty much any C++ features. In particular trying to pass a class type to a function with ellipsis arguments is bad bad mojo, since the constructor will probably be called when placing it on the stack and the destructor will not be called since the varidic function won't know how to clean it up.

##### Share on other sites
Always thought it should have been ellipsis but I was never sure.

##### Share on other sites
Thanks Chaps..

When you mentioned variadic functions, I looked this up on the GNU.org website:

#include <stdarg.h>#include <stdio.h>     intadd_em_up (int count,...){    va_list ap;    int i, sum;      va_start (ap, count);         /* Initialize the argument list. */         sum = 0;    for (i = 0; i < count; i++)      sum += va_arg (ap, int);    /* Get the next argument value. */         va_end (ap);                  /* Clean up. */    return sum;}     intmain (void){   /* This call prints 16. */   printf ("%d\n", add_em_up (3, 5, 5, 6));        /* This call prints 55. */   printf ("%d\n", add_em_up (10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10));      return 0;}

I understand what you mean now...passing objects here could be a disaster!

Thanks Chaps!

--random

##### Share on other sites
Quote:
 Original post by random_thinkerThanks Chaps..When you mentioned variadic functions, I looked this up on the GNU.org website:*** Source Snippet Removed ***I understand what you mean now...passing objects here could be a disaster!Thanks Chaps!--random

Try passing a std::string by value to printf. The results may surprise you.

MSN

##### Share on other sites
Quote:
 In particular trying to pass a class type to a function with ellipsis arguments is bad bad mojo, since the constructor will probably be called when placing it on the stack and the destructor will not be called since the varidic function won't know how to clean it up.

I think this reflects lack of understanding of the C calling convention. Despite the presence of "RET n" instructions that return from callee and adjust the stack (-> smaller code), the caller is responsible for cleanup. This is precisely because variadic functions do not know what was passed, but the caller (who pushed those params) does.

And I feel obligated to mention this every time the topic comes up: 1) printf has power unmatched by cout << and is quite concise 2) non-crappy compilers do type checking on known variadic functions!

##### Share on other sites
Quote:
Original post by Jan Wassenberg
Quote:
 In particular trying to pass a class type to a function with ellipsis arguments is bad bad mojo, since the constructor will probably be called when placing it on the stack and the destructor will not be called since the varidic function won't know how to clean it up.

I think this reflects lack of understanding of the C calling convention. Despite the presence of "RET n" instructions that return from callee and adjust the stack (-> smaller code), the caller is responsible for cleanup. This is precisely because variadic functions do not know what was passed, but the caller (who pushed those params) does.

And I feel obligated to mention this every time the topic comes up: 1) printf has power unmatched by cout << and is quite concise 2) non-crappy compilers do type checking on known variadic functions!

Jan,

Would you have a code example of how you'd clean up after using an elipsis construct on C++ objects? I'm curious as to how this should be done.

--random

##### Share on other sites
Quote:
 Original post by Jan WassenbergI think this reflects lack of understanding of the C calling convention. Despite the presence of "RET n" instructions that return from callee and adjust the stack (-> smaller code), the caller is responsible for cleanup. This is precisely because variadic functions do not know what was passed, but the caller (who pushed those params) does.

Whether or not it's supposed to happen. I've seen the kind of lack of destructor call problem happen in real code. IMO, it's not worth the risk to assume that the calling code will clean up properly.