www.digitalmars.com Home | Search | C & C++ | D | DMDScript | News Groups | index | prev | next
Archives

D Programming
D
D.gnu
digitalmars.D
digitalmars.D.bugs
digitalmars.D.dtl
digitalmars.D.dwt
digitalmars.D.announce
digitalmars.D.learn
digitalmars.D.debugger

C/C++ Programming
c++
c++.announce
c++.atl
c++.beta
c++.chat
c++.command-line
c++.dos
c++.dos.16-bits
c++.dos.32-bits
c++.idde
c++.mfc
c++.rtl
c++.stl
c++.stl.hp
c++.stl.port
c++.stl.sgi
c++.stlsoft
c++.windows
c++.windows.16-bits
c++.windows.32-bits
c++.wxwindows

digitalmars.empire
digitalmars.DMDScript

c++ - bugs in DMC 8.22

↑ ↓ ← Laurentiu Pancescu <plaur crosswinds.net> writes:
Sorry for the length of the post... ;)  I hope at least Walter
will read it!  There are some bugs, or at least different
behavior of DMC than standard says (BCC and GCC compile those
samples without any problems, for instance).

Bug #1
------------

// file: test1.cpp
#include <iostream.h>

class Test
{
public:
    Test(double a): x(a) {}
    double operator()(double b) { return x + b; }
private:
    double x;
};

int main()
{
    for (double v = 0.0; v < 1.0; v += 0.1)
    {
        cout << "Test: " << Test(v)(2.0) << endl;
    }
    return 0;
}

sc -c test1.cpp

        cout << "Test: " << Test(v)(2.0) << endl;
                                   ^
test1.cpp(16) : Error: illegal operand types
Had: void *
--- errorlevel 1

If I add a dummy constructor argument to Test, like:

Test(double a, double):x(a) {}
// ... same stuff here...
 for (double v = 0.0; v < 1.0; v += 0.1)
    {
        cout << "Test: " << Test(v, 3.0)(2.0) << endl;
    }

everything works fine.  As workaround for a single arg, we can
declare a temp variable:

for(double v = 0.0; v < 1.0; v += 0.1)
{
  Test aux(v);
  cout << aux(2.0) << endl;
}

Bug #2
-----------------------

// cst.h
#ifndef __CST_H__
#define __CST_H__
extern const char hello[];
#endif

// cst.cpp
extern const char hello[] = "Hello, DMC!!";

// test2.cpp
#include "cst.h"
#include <iostream.h>

int main()
{
  cout << hello << endl;
  return 0;
}

sc -otest2.exe test2.cpp cst.cpp
test2.cpp:
cst.cpp:
link test2+cst,test2.exe,,user32+kernel32/noi;
OPTLINK (R) for Win32  Release 7.50B1
Copyright (C) Digital Mars 1989 - 2001  All Rights Reserved

test2.obj(test2)
 Error 42: Symbol Undefined ?hello  3QBDB (const char const
*const hello)

--- errorlevel 1

Workaround: use extern "C" instead of plain extern.  BTW, isn't
there a const too many?  const char hello[] should be
equivalent with 'const char * const hello', right?

Bug #3
---------------

Well, mostly wishlist: correct scoping of variables declared in
for loops, like in "for (unsigned i = 0; i < 3; i++) {}"...
there should be no more i visible after for.  Maybe Walter could
do this easily (eventually Borland style, with a command line
switch, not to ruin compatibility with old code).

And also for Walter: the difference between <stdio.h> and
<cstdio>, or any other old "C" headers and new method in ANSI-C++,
is that C's standard functions are put into namespace std,
intead of the global namespace.  DMC doesn't do this, unfortunately.
 How about using the gcc 2.95.x method of considering
namespace std an alias of the global namespace, unless told otherwise
(with -fhonor-std).

These are probably easy to do, and will save some of us from a
lot of editing of ANSI-C++ code, for making it compilable with
DMC.  Also, iostreams headers without trailing '.h' would be nice... :)


Regards,
  Laurentiu Pancescu
Nov 04 2001
↑ ↓ → "Walter" <walter digitalmars.com> writes:
Thanks!

"Laurentiu Pancescu" <plaur crosswinds.net> wrote in message
news:9s4aor$9jv$1 digitaldaemon.com...
 Sorry for the length of the post... ;)  I hope at least Walter
 will read it!  There are some bugs, or at least different
 behavior of DMC than standard says (BCC and GCC compile those
 samples without any problems, for instance).

 Bug #1
 ------------

 // file: test1.cpp
 #include <iostream.h>

 class Test
 {
 public:
     Test(double a): x(a) {}
     double operator()(double b) { return x + b; }
 private:
     double x;
 };

 int main()
 {
     for (double v = 0.0; v < 1.0; v += 0.1)
     {
         cout << "Test: " << Test(v)(2.0) << endl;
     }
     return 0;
 }

 sc -c test1.cpp

         cout << "Test: " << Test(v)(2.0) << endl;
                                    ^
 test1.cpp(16) : Error: illegal operand types
 Had: void *
 --- errorlevel 1

 If I add a dummy constructor argument to Test, like:

 Test(double a, double):x(a) {}
 // ... same stuff here...
  for (double v = 0.0; v < 1.0; v += 0.1)
     {
         cout << "Test: " << Test(v, 3.0)(2.0) << endl;
     }

 everything works fine.  As workaround for a single arg, we can
 declare a temp variable:

 for(double v = 0.0; v < 1.0; v += 0.1)
 {
   Test aux(v);
   cout << aux(2.0) << endl;
 }

 Bug #2
 -----------------------

 // cst.h
 #ifndef __CST_H__
 #define __CST_H__
 extern const char hello[];
 #endif

 // cst.cpp
 extern const char hello[] = "Hello, DMC!!";

 // test2.cpp
 #include "cst.h"
 #include <iostream.h>

 int main()
 {
   cout << hello << endl;
   return 0;
 }

 sc -otest2.exe test2.cpp cst.cpp
 test2.cpp:
 cst.cpp:
 link test2+cst,test2.exe,,user32+kernel32/noi;
 OPTLINK (R) for Win32  Release 7.50B1
 Copyright (C) Digital Mars 1989 - 2001  All Rights Reserved

 test2.obj(test2)
  Error 42: Symbol Undefined ?hello  3QBDB (const char const
 *const hello)

 --- errorlevel 1

 Workaround: use extern "C" instead of plain extern.  BTW, isn't
 there a const too many?  const char hello[] should be
 equivalent with 'const char * const hello', right?

 Bug #3
 ---------------

 Well, mostly wishlist: correct scoping of variables declared in
 for loops, like in "for (unsigned i = 0; i < 3; i++) {}"...
 there should be no more i visible after for.  Maybe Walter could
 do this easily (eventually Borland style, with a command line
 switch, not to ruin compatibility with old code).

 And also for Walter: the difference between <stdio.h> and
 <cstdio>, or any other old "C" headers and new method in ANSI-C++,
 is that C's standard functions are put into namespace std,
 intead of the global namespace.  DMC doesn't do this, unfortunately.
  How about using the gcc 2.95.x method of considering
 namespace std an alias of the global namespace, unless told otherwise
 (with -fhonor-std).

 These are probably easy to do, and will save some of us from a
 lot of editing of ANSI-C++ code, for making it compilable with
 DMC.  Also, iostreams headers without trailing '.h' would be nice... :)


 Regards,
   Laurentiu Pancescu

Nov 04 2001