tags:

views:

136

answers:

3

Accidential use of classes inside of c style typeless variable arguments list is a common error source. Example:

class MyString {
    public:
    char *pChars;
    int Length;

    MyString(char *pChars) {
        this->pChars = pChars; 
        Length = strlen(pChars); 
        } };

int main() {
    MyString s1("Bla1"), s2("Bla2");
    printf("%s%s", s1, s2); // This does not but should give a compiler warning/error!
    return 0; }

The printf call there receives the two s objects by value. that means all of their members are simply memory copied. But they are interpreted a simple char pointers. Result is a runtime error of course.

I am not asking for a solution to this, but I would like to have something I could add to my class so that the compiler warns me about it or gives an error.

Already tried to declarate but not implement a copy constructor. But it seems that no copy constructor is called. :-(

Please just answer to the question in the title. I do not need a discusson of why you should not use printf or these variable arguments lists - know that.

Thanks for your time.

+9  A: 

Decent compilers (like gcc) check whether printf arguments match format specifiers in format string.

Just do not forget to add -Wformat or -Wall command line option.

http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html

qrdl
Well, maybe visual C++ is no descent compiler?
kaptnole
@kaptnole they postponed on the decency, at least regarding the issue you're experiencing :) http://connect.microsoft.com/VisualStudio/feedback/details/98899/compiler-should-warn-about-passing-objects-of-non-pod-types-to-the-ellipsis. I know you don't want to hear this but don't use printf see advices here http://stackoverflow.com/questions/2017489/should-i-use-printf-in-my-c-code
celavek
@celavek I would have accepted your comment as an answer if you would have posted it as one :-)
kaptnole
@kaptnole well ... tough luck :)
celavek
A: 

Derive from boost::noncopyable

Sebastian
That's equivalent to Cătălin's answer, and has the same problem; it won't prevent passing through `...`, since that gives undefined behaviour, not a copy.
Mike Seymour
A: 

Hide copy constructor and assignment operator (declare them private, no need to implement them). Or derive the class from boost::noncopyable (which has the same effect).Passing arguments by value determines the usage of the copy constructor.

Cătălin Pitiș
Except this doesn't help because the instance is not passed by value, but rather some raw bytes are passed and then `reinterpret_cast` -ed to `const char*`. I don't think there is a language-level means to avoid the situation. You can only depend on the compiler warning (e.g "cannot pass non-POD object through ...")
visitor
@Cătălin Pitiș: Well the OP said in his question already that he played with the copy constructor. Do you think that also overloading the assignment operator will change the behavior? Is that a feature/bug of visual c++?
Jens Gustedt
does not work, no copy/assignment constructors called
kaptnole