unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
* SCM_POSFIXABLE(-1) fails with MSVC++ 6.0
@ 2002-08-22 13:30 Lars J. Aas
  2002-08-22 13:47 ` Lars J. Aas
  0 siblings, 1 reply; 7+ messages in thread
From: Lars J. Aas @ 2002-08-22 13:30 UTC (permalink / raw)


  Hi guys,

I've been compiling Guile 1.5.6 with MSVC++ on Cygwin.
Today I found a strange bug in my modified version, that
made this test fail:

  (if (= ( { scm_long2num(-1) } ) -1)
      (display "there is no bug\n")
      (display "there is a bug!\n"))

I tracked the problem down to SCM_POSFIXABLE(-1) failing
with MSVC++, causing scm_long2num(-1) to create a bignum
instead of an integer, but succeeding on GNU/Linux w/gcc.
I don't see immediately why it should happen - it looks
like a compiler bug to me.

Here is a fairly minimal example.  If anyone has access to
MSVC++ and can understand why it fails and how to correct
the SCM_POSFIXABLE macro to work with MSVC++, it would be
very nice, and ought to go into the Guile sources too.

  Lars J


#include <stdio.h>
#include <limits.h>

typedef signed long scm_t_signed_bits;

#ifdef CHAR_BIT
# define SCM_CHAR_BIT CHAR_BIT
#else
# define SCM_CHAR_BIT 8
#endif

#ifdef LONG_BIT
# define SCM_LONG_BIT LONG_BIT
#else
# define SCM_LONG_BIT (SCM_CHAR_BIT * sizeof (long) / sizeof (char))
#endif

#define SCM_I_FIXNUM_BIT \
  (SCM_LONG_BIT - 2)

#define SCM_MOST_POSITIVE_FIXNUM \
  ((((scm_t_signed_bits) 1) << (SCM_I_FIXNUM_BIT - 1)) - 1)

#define SCM_POSFIXABLE(n) ((n) <= SCM_MOST_POSITIVE_FIXNUM)

int
main(int argc, char ** argv)
{
  fprintf(stderr, "testing through SCM_POSFIXABLE if -1 is <= %ld - ", SCM_MOST_POSITIVE_FIXNUM);
  if ( SCM_POSFIXABLE(-1) ) fprintf(stderr, "true\n");
  else                      fprintf(stderr, "not so!\n");

  fprintf(stderr, "testing directly if -1 is <= %ld - ", SCM_MOST_POSITIVE_FIXNUM);
  if ( -1 <= 536870911 ) fprintf(stderr, "true\n");
  else                   fprintf(stderr, "not so!\n");

  return 0;
}



_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-devel


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: SCM_POSFIXABLE(-1) fails with MSVC++ 6.0
  2002-08-22 13:30 SCM_POSFIXABLE(-1) fails with MSVC++ 6.0 Lars J. Aas
@ 2002-08-22 13:47 ` Lars J. Aas
  2002-08-23 10:40   ` Lars J. Aas
  0 siblings, 1 reply; 7+ messages in thread
From: Lars J. Aas @ 2002-08-22 13:47 UTC (permalink / raw)


Lars J. Aas <larsa@sim.no> wrote:
: #ifdef LONG_BIT
: # define SCM_LONG_BIT LONG_BIT
: #else
: # define SCM_LONG_BIT (SCM_CHAR_BIT * sizeof (long) / sizeof (char))
: #endif

I boiled the problem down to this test failing:

  fprintf(stderr, "testing directly if -1 is <= sizeof(long) ");
  if ( -1 <= sizeof(long) ) fprintf(stderr, "true\n");
  else                      fprintf(stderr, "not so!\n");

Changing the alternative definition of SCM_LONG_BITS to cast the value
to long like this works...

# define SCM_LONG_BIT ((long)(SCM_CHAR_BIT * sizeof (long) / sizeof (char)))

  Lars J


_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-devel


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: SCM_POSFIXABLE(-1) fails with MSVC++ 6.0
  2002-08-22 13:47 ` Lars J. Aas
@ 2002-08-23 10:40   ` Lars J. Aas
  2002-08-24  7:42     ` Dirk Herrmann
  0 siblings, 1 reply; 7+ messages in thread
From: Lars J. Aas @ 2002-08-23 10:40 UTC (permalink / raw)


Lars J. Aas <larsa@sim.no> wrote:
: Changing the alternative definition of SCM_LONG_BITS to cast the value
: to long like this works...
: 
: # define SCM_LONG_BIT ((long)(SCM_CHAR_BIT * sizeof (long) / sizeof (char)))

Come to think of it, the cast is better placed on the inside so it's more
evident what is being done (stopping the unsigned-ness of the sizeof()-
operations to propagate incorrectly out through the macro invokation) so
it's not removed later by someone not knowing about this compiler bug.

# define SCM_LONG_BIT (SCM_CHAR_BIT * ((long) (sizeof (long) / sizeof (char))))

or s/long/int/ on the cast?

BTW, is anyone reading these mails? ;)

  Lars J


_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-devel


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: SCM_POSFIXABLE(-1) fails with MSVC++ 6.0
  2002-08-23 10:40   ` Lars J. Aas
@ 2002-08-24  7:42     ` Dirk Herrmann
  2002-08-24 15:57       ` Lynn Winebarger
  2002-08-25 13:27       ` Lars J. Aas
  0 siblings, 2 replies; 7+ messages in thread
From: Dirk Herrmann @ 2002-08-24  7:42 UTC (permalink / raw)
  Cc: Guile Devel

On Fri, 23 Aug 2002, Lars J. Aas wrote:

> Lars J. Aas <larsa@sim.no> wrote:
> : Changing the alternative definition of SCM_LONG_BITS to cast the value
> : to long like this works...
> : 
> : # define SCM_LONG_BIT ((long)(SCM_CHAR_BIT * sizeof (long) / sizeof (char)))
> 
> Come to think of it, the cast is better placed on the inside so it's more
> evident what is being done (stopping the unsigned-ness of the sizeof()-
> operations to propagate incorrectly out through the macro invokation) so
> it's not removed later by someone not knowing about this compiler bug.
> 
> # define SCM_LONG_BIT (SCM_CHAR_BIT * ((long) (sizeof (long) / sizeof (char))))
> 
> or s/long/int/ on the cast?
> 
> BTW, is anyone reading these mails? ;)
> 
>   Lars J

I am not sure I understand the problem here:  is the failure of testing 
-1 <= sizeof(long) a compiler bug, or is the strange behaviour defined
in the C language?

Best regards,
Dirk Herrmann



_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-devel


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: SCM_POSFIXABLE(-1) fails with MSVC++ 6.0
  2002-08-24  7:42     ` Dirk Herrmann
@ 2002-08-24 15:57       ` Lynn Winebarger
  2002-08-25 13:27       ` Lars J. Aas
  1 sibling, 0 replies; 7+ messages in thread
From: Lynn Winebarger @ 2002-08-24 15:57 UTC (permalink / raw)


On Saturday 24 August 2002 02:42, Dirk Herrmann wrote:
> 
> I am not sure I understand the problem here:  is the failure of testing 
> -1 <= sizeof(long) a compiler bug, or is the strange behaviour defined
> in the C language?

    It is mandated by K&R 2nd edition (Section A6).  When an expression
has and unsigned long and a signed long, the signed long is promoted to unsigned,
but without any change to the actual bit representation.  Thus -1 is 2^32-1, which
is clearly bigger than sizeof(long).  If you really want to compare to -1, cast the
unsigned to signed (since we know it'll fit in this case, and if promoted, will still give
the correct result (that is, if compared to an unsigned quantity, it will get recast to
unsigned, only this time the cast will get it right)).
     So gcc's probably wrong on this.  Apparently their optimization pass does its 
constant folding with a more accurate notion of integers than the machine code
has.
     It's possible this has been changed, but I would find it hard to believe as it
would change the semantics of so many programs.

Lynn
      


_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-devel


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: SCM_POSFIXABLE(-1) fails with MSVC++ 6.0
  2002-08-24  7:42     ` Dirk Herrmann
  2002-08-24 15:57       ` Lynn Winebarger
@ 2002-08-25 13:27       ` Lars J. Aas
  2002-08-25 16:01         ` Lynn Winebarger
  1 sibling, 1 reply; 7+ messages in thread
From: Lars J. Aas @ 2002-08-25 13:27 UTC (permalink / raw)
  Cc: Guile Devel

Dirk Herrmann <dirk@sallust.ida.ing.tu-bs.de> wrote:
: On Fri, 23 Aug 2002, Lars J. Aas wrote:
: 
: > Lars J. Aas <larsa@sim.no> wrote:
: > : Changing the alternative definition of SCM_LONG_BITS to cast the value
: > : to long like this works...
: > : 
: > : # define SCM_LONG_BIT ((long)(SCM_CHAR_BIT * sizeof (long) / sizeof (char)))
: > 
: > Come to think of it, the cast is better placed on the inside so it's more
: > evident what is being done (stopping the unsigned-ness of the sizeof()-
: > operations to propagate incorrectly out through the macro invokation) so
: > it's not removed later by someone not knowing about this compiler bug.
: > 
: > # define SCM_LONG_BIT (SCM_CHAR_BIT * ((long) (sizeof (long) / sizeof (char))))
: > 
: > or s/long/int/ on the cast?
: > 
: > BTW, is anyone reading these mails? ;)
: > 
: >   Lars J
: 
: I am not sure I understand the problem here:  is the failure of testing 
: -1 <= sizeof(long) a compiler bug, or is the strange behaviour defined
: in the C language?

I haven't studied the C specification under a microscope, but it has got
to be a compiler bug.  What I guess is happening is that sizeof() is defined
to return an unsigned value, and consequently -1 is interpreted as an unsigned
value.  Exactly how data type qualifiers are supposed to propagate over unary
tests isn't something I know for sure, but gcc handles it as one would expect.

BTW, I don't think the define makes sense at all.  I believe it's part of
the C standard that sizeof(char) should always return 1, whether the char type
is the size of a byte or not.  Besides, if it had returned the number of bytes
a char is - why would one want to divide by it?  Multiply perhaps, but that
would only be if sizeof(long) returned the number of _chars_ in a long, and
sizeof(char) returned the number of _bytes_ in a char, which wouldn't make
sense either.  So there's some stuff I think is wrong there, but I guess that
part of the #if/else isn't that often used, and when it's used, it doesn't
affect the result since it's a divide-by-one thing and char is always a byte
long.

I propose that the define is changed to:

# define SCM_LONG_BIT (SCM_CHAR_BIT * ((int) sizeof(long)))

  Lars J


_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-devel


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: SCM_POSFIXABLE(-1) fails with MSVC++ 6.0
  2002-08-25 13:27       ` Lars J. Aas
@ 2002-08-25 16:01         ` Lynn Winebarger
  0 siblings, 0 replies; 7+ messages in thread
From: Lynn Winebarger @ 2002-08-25 16:01 UTC (permalink / raw)


On Sunday 25 August 2002 08:27, Lars J. Aas wrote:
> Dirk Herrmann <dirk@sallust.ida.ing.tu-bs.de> wrote:
> : 
> : I am not sure I understand the problem here:  is the failure of testing 
> : -1 <= sizeof(long) a compiler bug, or is the strange behaviour defined
> : in the C language?
> 
> I haven't studied the C specification under a microscope, but it has got
> to be a compiler bug.
    Nope.  It's a completely natural consequence or promoting signed to 
unsigned and the 2 values having the same storage size (and that being
the largest that will fit in a register).

>  What I guess is happening is that sizeof() is defined
> to return an unsigned value, and consequently -1 is interpreted as an unsigned
> value.  Exactly how data type qualifiers are supposed to propagate over unary
> tests isn't something I know for sure, but gcc handles it as one would expect.

    Well, I went back and looked at the original code versus what you said
it boils down to (the 3 lines).  With gcc, the first program returns true in both 
cases, but the 2nd (3 lines) prints "not so".  So gcc does get it right.  In the
original code you posted, the right hand side is cast to be a signed value
(scm_t_signed_bits) so it should get compared properly whether the left
hand side is signed or unsigned (and it does). 
     So I guess MSVC has a bug.
     As for the division by sizeof(char), though, I have no idea.  Maybe someone
was working with a non-standards-compliant compiler?

Lynn


_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-devel


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2002-08-25 16:01 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-08-22 13:30 SCM_POSFIXABLE(-1) fails with MSVC++ 6.0 Lars J. Aas
2002-08-22 13:47 ` Lars J. Aas
2002-08-23 10:40   ` Lars J. Aas
2002-08-24  7:42     ` Dirk Herrmann
2002-08-24 15:57       ` Lynn Winebarger
2002-08-25 13:27       ` Lars J. Aas
2002-08-25 16:01         ` Lynn Winebarger

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).