open-watcom / open-watcom-v2

Open Watcom V2.0 - Source code repository, Wiki, Latest Binary build, Archived builds including all installers for download.
Other
985 stars 160 forks source link

C++ compiler accepts incompatible method which causes code malfunction #1052

Open rdos314 opened 1 year ago

rdos314 commented 1 year ago

Example code:

#include <string.h>
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>

class TMyClass
{
public:
    TMyClass();
   ~TMyClass();
    void printf(const char *frm, va_list args);
};

TMyClass::TMyClass()
{
}

TMyClass::~TMyClass()
{
}

void TMyClass::printf(const char *frm, va_list args)
{
    printf(frm, args);
}

void main()
{
    int probe = 3;
    char temp[20];
    TMyClass my;

    sprintf(temp, "$B%02d", probe);
    my.printf("%s", temp);
}

The old version of the compiler will emit E473 for this code. The new compiler will accept it and generate code that doesn't work.

Perhaps the most serious in this scenario is that if a matching method like int printf(const char *fmt, ...); is added, the old compiler will use the matching method while the new will still use the faulty method that doesn't work.

It seems like this is only an issue in C++ as the same code works just fine if used as C code.

joncampbell123 commented 10 months ago

Try changing TMyClass::printf() to this instead:

void TMyClass::printf(const char *frm, va_list args)
{
    ::printf(frm, args);
}

You need the :: before printf() inside to refer to the global scope printf you intend to use. This isn't an Open Watcom bug, you'll get the same infinite recursion with GCC if you compile that. It's a matter of scope, since your C++ class defined it's own printf() that comes first when the compiler looks up which symbol to match it to.

jmalak commented 10 months ago

Example code:

#include <string.h>
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>

class TMyClass
{
public:
    TMyClass();
   ~TMyClass();
    void printf(const char *frm, va_list args);
};

TMyClass::TMyClass()
{
}

TMyClass::~TMyClass()
{
}

void TMyClass::printf(const char *frm, va_list args)
{
    printf(frm, args);
}

void main()
{
    int probe = 3;
    char temp[20];
    TMyClass my;

    sprintf(temp, "$B%02d", probe);
    my.printf("%s", temp);
}

The old version of the compiler will emit E473 for this code. The new compiler will accept it and generate code that doesn't work.

Perhaps the most serious in this scenario is that if a matching method like int printf(const char *fmt, ...); is added, the old compiler will use the matching method while the new will still use the faulty method that doesn't work.

It seems like this is only an issue in C++ as the same code works just fine if used as C code.

Please specify what you mean by "old version of compiler".