HDTenEightyP/NetNews huggingface dataset:
From: diamond@jit533.jit.dec.com (Norman Diamond)
Subject: Re: Is INT_MAX<<1 defined?
Reply-To: diamond@jit.dec.com (Norman Diamond)
Organization: Digital Equipment Corporation Japan , Tokyo
Date: Mon, 14 Dec 1992 07:15:16 GMT

In article <8322@charon.cwi.nl> dik@cwi.nl (Dik T. Winter) writes:
>What it comes down to is that << is not a mathematical operation, there
>is nothing in mathematics that tells us that 16384 << 1 equals 32768.

Additional non-mathematical operations:
  ++ (prefix and postfix)
  -- (prefix and postfix)
  [] (subscript, C definition using pointers)
  () (function call, C definition using pointers)
  () (cast)
  unary  &  *  !
  unary  ~  on a value that is not a single bit
  binary /  on integral values where the mathematical quotient is not integral
  binary .  ->  sizeof  %  &  ^  |  &&  ||  =  *=(etc.)  ,

>So what is the meaning of:
>1.  Operation on value in this case?

Operations have meanings defined in the C standard.  For "value", it looks
like we have to refer to another standard.  The ANSI C standard, section 1.6,
page 4 lines 3 to 5, says:  "Terms not defined in this Standard are to be
interpreted according to the American National Dictionary for Information
Processing Systems, Information Processing Systems Technical Report ANSI
X3/TR-1-82 (1982)."  I don't know the ISO equivalent.

>    Where in the standard does it tell
>    us that for signed (16 bit) int 16384, 16384 << 1 is 32768?

I think the standard is unclear enough to recommend an interpretation ruling.
However, for comparison, for unsigned types, the standard says explicitly
that the value of the result is a mathematical multiplication followed by
a mathematical modulo reduction -- if it were a representation multiplication,
the modulo reduction would have been a no-op and would not have been stated.

>    Is an implementation not allowed to define it as -32768?  Or whatever?

Implementations are allowed to define what happens when signed results don't
fit in the corresponding types.  They aren't REQUIRED to, that's all.

>    But in all there is no definition in *mathematics* for this operation.
[...]
>The bottom-line is that shifting is not a mathematical concept, [...]

That didn't prevent a ton of other C operations from being defined on
mathematical values.  Actually maybe the standards committees can start
to get an idea of just how unpopular this stunt is.  However, that is what
they did, following the path of other language committees.
--
Norman Diamond       diamond@jit081.enet.dec.com
If this were the company's opinion, I wouldn't be allowed to post it.
"It's been a lovely recession."
Newsgroups: comp.std.c
From: hoesel@igc.ethz.ch (Frans van Hoesel)
Subject: are float functions (sinf, fabsf) required by ansi?
Organization: University of Groningen, the Netherlands
Date: Fri, 18 Dec 1992 23:26:21 GMT

The subject is clear enough... must any ansi compiler know the functions
for evaluating sin with a float argument (after including math.h) and
is it always called sinf. Or rephrased... is sinf in the standard library?

easy enough, but K&R mentions only sin, not sinf. My environment (SGI indigo)
has sinf, but does not state cleary if sinf is standard.

-- frans
-- 
--    ==============================================================    --
----  ===  frans van hoesel             hoesel@igc.ethz.ch       ===  ----
--    ==============================================================    --
Newsgroups: comp.std.c
From: gordon@sneaky.lonestar.org (Gordon Burditt)
Subject: Re: are float functions (sinf, fabsf) required by ansi?
Organization: Gordon Burditt
Date: Sun, 20 Dec 1992 19:55:49 GMT

>The subject is clear enough... must any ansi compiler know the functions
>for evaluating sin with a float argument (after including math.h) and
>is it always called sinf. Or rephrased... is sinf in the standard library?

No.

However, ANSI does reserve the names of functions in <math.h> suffixed
with f or l under 4.13 "Future Library Directions".

					Gordon L. Burditt
					sneaky.lonestar.org!gordon
From: pal@regent.e-technik.tu-muenchen.dbp.de (Peter Loibl)
Subject: Re: (long) x and (long) floor(x)
Organization: Technical University of Munich, Germany
Date: Mon, 14 Dec 1992 15:43:32 GMT

pjh@cs.tut.fi (Haavisto Petri) writes:

>I just spent several hours debugging a simple program and before
>crying Compiler Bug I would like to make sure that there is one.

>I don't have the standard, but it seems clear to me that given an
>expression of type double with a positive value, the following
>should always be true:

>		(long) (expression) == (long) floor(expression)

>Does the standard guarantee this or is there a loop hole that has to
>do with finite precision arithmetic and which allows the compiler to
>do what it chooses?

I don't have the standard at hand right now, but
        (long) (expression) == (long) floor((double)expression)
should be true.                              ^^^^^^

Peter Loibl
pal@regent.e-technik.tu-muenchen.de
From: scjones@thor.sdrc.com (Larry Jones)
Newsgroups: comp.std.c
Subject: Re: float to cond conversions
Date: 12 Dec 92 20:11:49 GMT

In article <1992Dec09.011729.20954@Veritas.COM>, joshua@Veritas.COM (Joshua Levy) writes:
> Consider the following code:
>    int same(int b) { return b ; }
>    if (X)
>    if (same(!!(X)))
>    if (same((int)(X))))
>    X can be any legal C code including something like "f == 4.0"
>    where f is a float or a double.
> 
> If I have an ANSI C compiler, are either of the second two if statements
> identical in behavior to the first if statement?

Yes, the second one is.

First, note that your same() function is, at best, a long-winded way to
write an (int) cast and, at worst, a noop.  Thus, the second and third
if statements are equivalent to:
	if ((int)!!(X))
	if ((int)(int)(X))
Since the result of the ! operator is already an int and you already had
an explicit (int) cast in the third if statement, same() is a complete
noop in both of the cases which then degerate to:
	if (!!(X))
	if ((int)(X))

Now, let's write out the implicit comparisons with 0 explicitly:
	if ((X) != 0)
	if (!((X) == 0))  => if ((X) != 0)
	if ((int)(X) != 0)

It's now obvious that the first and second statements are identical and
the third satement is also identical *if X has an integral value*.  If X
has a non-integral value like 0.1, the first two statements will be true
but the third will be false.

> I'm also interested in knowing if either of the second two if statements
> will have different behavior in any common K&R C compiler.

No, but a K&R compiler will not automatically convert the argument to
same() to int the way an ANSI compiler will (given a prototype).
----
Larry Jones, SDRC, 2000 Eastman Dr., Milford, OH  45150-2789  513-576-2070
larry.jones@sdrc.com  or  ...uunet!sdrc!larry.jones
I sure wish I could get my hands on some REAL dynamite. -- Calvin
From: gwyn@smoke.brl.mil (Doug Gwyn)
Newsgroups: comp.std.c
Subject: <iso646.h>
Keywords: Standard C international header implementation
Date: 13 Dec 92 08:18:51 GMT
Organization: U.S. Army Ballistic Research Lab (BRL), APG, MD.

/*
	<iso646.h> -- macros for use in place of certain tokens that are
		not expressible in the invariant subset of ISO 646:1991

	public-domain implementation for all versions of C

	last edit:	13-Dec-1992	Gwyn@ARL.Army.Mil

	complies with the following standard:
		ANSI/ISO 9899:1990[1992] (as expected to be amended in 1993)

	Usage:	??=include <iso646.h>

	Notes:	The C standard has always required that the following
		trigraphs be supported in translation phase 1:
			??= mapped to #
			??( mapped to [
			??/ mapped to \
			??) mapped to ]
			??' mapped to ^
			??< mapped to {
			??! mapped to |
			??> mapped to }
			??- mapped to ~

		The forthcoming normative addendum to the C standard that
		requires conforming implementations to provide <iso646.h>
		also requires support in translation phases 3..4 for the
		following preprocessing tokens:
			%: alternate spelling for #
			%:%: alternate spelling for ##
		It also requires support in translation phases 3..7 for the
		following preprocessing tokens:
			<% alternate spelling for {
			%> alternate spelling for }
			<: alternate spelling for [
			:> alternate spelling for ]

		The C standard also requires that the "difficult" characters
		be somehow provided in both the basic source and execution
		character sets, regardless of the provision of trigraph,
		digraph, and macro alternatives for these characters.

		It is suggested that all C programmers avoid use of the
		following identifiers in their programs, in case somebody
		later needs to use <iso646.h> in maintaining the programs.
 */

#define or	||
#define bitor	|
#define or_eq	|=
#define xor	^
#define xor_eq	^=
#define compl	~
#define and	&&
#define bitand	&
#define and_eq	&=
#define not	!
#define ne	!=
From: pjh@cs.tut.fi (Haavisto Petri)
Newsgroups: comp.std.c
Subject: (long) x and (long) floor(x)
Date: 14 Dec 1992 12:05:43 GMT
Organization: Tampere University of Technology
Distribution: world
NNTP-Posting-Host: vuoripyy.cs.tut.fi


I just spent several hours debugging a simple program and before
crying Compiler Bug I would like to make sure that there is one.

I don't have the standard, but it seems clear to me that given an
expression of type double with a positive value, the following
should always be true:

		(long) (expression) == (long) floor(expression)

Does the standard guarantee this or is there a loop hole that has to
do with finite precision arithmetic and which allows the compiler to
do what it chooses?

Petri Haavisto

PS. For those who might be interested, the compiler that caused the
problems was Microsoft C (version 6.something) for MSDOS.
From: scjones@thor.sdrc.com (Larry Jones)
Newsgroups: comp.std.c
Subject: Re: definition of strNcpy
Date: 18 Dec 92 15:49:46 GMT

In article <1992Dec18.015228.6094@dms.agames.com>, lipson@dms.agames.com (Pete Lipson) writes:
>   if you say:   strncpy(dst,"abcdef",4)
> 
>  does the standard really say you get five characters appended to the
> dst (the chars 'a' 'b' 'c' 'd' AND the '\0') ???

You talk about strncpy, but then you talk about characters being appended;
are you really talking about strncpy() or did you mean strncat()?!?

If you really mean strncpy(), then it should replace the first four
characters of dst with 'a', 'b', 'c', and 'd' with no NUL.

If you mean strncat(), then what you described is exactly right: it
should append at most 4 characters and then add a NUL.
----
Larry Jones, SDRC, 2000 Eastman Dr., Milford, OH  45150-2789  513-576-2070
larry.jones@sdrc.com  or  ...uunet!sdrc!larry.jones
Well of course the zipper's going to get stuck if everyone
stands around WATCHING me! -- Calvin
From: jfw@ksr.com (John F. Woods)
Newsgroups: comp.std.c
Subject: Re: <iso646.h>
Keywords: Standard C international header implementation
Date: 14 Dec 92 17:36:19 EST

mcdaniel@grex.ann-arbor.mi.us (Tim McDaniel) writes:
>What is a "normative addendum"?

It seems to be the ISO's way of fixing standards that aren't broken ;-).

>What insane asylum added digraphs to the existing trigraph mess, and
>also said that the "difficult" characters have to exist anyway?  What's
>the point of trigraphs and digraphs then?

The point of trigraphs is that *terminals* don't have to have the "difficult"
characters, and that the "difficult" characters don't need to have the same
representations between implementations (and may well not, in an environment
where national characters have gobbled up the ASCII values for the "difficult"
characters).  The chief "use" of trigraphs seems to be as an exchange medium;
as long as two sites agree at least on the "easy" characters' values, then a
trigraphed source on tape can be written at one site and read at the other.
Of course, why it was necessary to do violence to the language in order to
avoid having an occasional tape accompanied by a handwritten note and/or a
quickie conversion utility has escaped many people...

>What fool made these identifiers ("or", "ne", ...) reserved?
As near as I can tell, no one made those identifiers reserved; Doug Gwyn seems
to have merely suggested them as an alternative for some reason only he can
definitively comment on (but I'll bet it was to head off a THIRD (and FOURTH
and FIFTH...) insane incomprehensible mapping scheme ("characters not available
in all national character sets will be encoded as :::::0000000000:::::, where
the string of 0's shall be replaced with a CCITT checksum of the Latin-1 name
of the original character....")).
From: christos@kuhub.cc.ukans.edu
Newsgroups: comp.std.c
Subject: C VS Fortran on UNIX
Date: 19 Dec 92 15:12:01 CST
Organization: University of Kansas Academic Computing Services

Hello there,

	I am going to write a program for number crunching on UNIX. I am
considering between Fortan and C and I am wondering which one would be faster or
what factors would affect the speed of the program.

	I would appreciate any advise.

Thanks,
Chris.
Internet Address: christos@kuhub.cc.ukans.edu
Xref: sparky comp.std.c:3243 comp.lang.c:18726
From: mouse@thunder.mcrcim.mcgill.edu (der Mouse)
Newsgroups: comp.std.c,comp.lang.c
Subject: Re: typedef void (*generic)()
Date: 21 Dec 92 00:15:37 GMT
Followup-To: comp.lang.c
Organization: McGill Research Centre for Intelligent Machines

In article <1992Dec16.172748.24120@bernina.ethz.ch>, hoesel@igc.ethz.ch (Frans van Hoesel) writes:

> I have a problem in doing what I want to do in c.

> typedef void (*generic)();

>         f = (generic) printf;
>         g = (generic) abs;

> 	/* and now do something like :printf("some text %d\n",abs(i)
> 	  ), but using f and g instead !*/

> This isn't the right group to ask (I know), but propably the best

Asking elsewhere than in the right group is never best.  I'm taking
steps to move it to comp.lang.c, since it really is not a standard
question, but a generic C question.

As for how you'd do it,

(*(int (*)(const char *, ...))f)("some text %d\n",(*(int (*)(int))g)(i));

Note the casts on the functions!  The compiler may be using different
calling sequences depending on the argument pattern and return type, so
for the calls to work you must cast the pointers correctly.  (The two
"(*(" sequences may be replaced by "((" instead; I just happen to like
to follow my function pointers before calling them.)

> There is also a remark from my compiler on some constructs stating
> that void pointer cannot be cast to function pointers.  Is this
> allowed?

Only in the special case of a null pointer constant.  Object pointers
and function pointers are not, in general, interconvertible.

					der Mouse

			    mouse@larry.mcrcim.mcgill.edu
Newsgroups: comp.std.c
From: diamond@jit533.jit.dec.com (Norman Diamond)
Subject: Re: Is INT_MAX<<1 defined?
Reply-To: diamond@jit.dec.com (Norman Diamond)
Organization: Digital Equipment Corporation Japan , Tokyo
Date: Wed, 16 Dec 1992 01:33:08 GMT

In article <1992Dec15.142103.49328@news.th-darmstadt.de> wallmann@backus.pu.informatik.th-darmstadt.de (Natuerlich!) writes:
>What I expect to happen in expressions like these:   INT_MAX << 1
>is that the compiler behaves as if it were ultralame.

K&R defined C to be ultralame (as a replacement for assembly language),
except that optimizations could range from ultrlame to (sometimes) unsafe.
That's somewhat a different language from what we're dealing with now.

>It acts as if it doesn't precompute at compiletime but rather computes the
>result at runtime.

In both K&R-1 and in ANSI/ISO C, it doesn't matter if this gets precomputed
or not.  The execution of the program can't distinguish.  This entire
discussion has not been trying to distinguish such a point.

>So that in fact the default type for INT_MAX is signed int (since there
>isn't an U or an L anywhere) and the shifting operation operates on a
>signed int on that system.

INT_MAX is always signed int, for the reason you gave.  The word "default"
is meaningless here.  The shift operation operates on a signed int.

>If you want portability you write  (long) INT_MAX * 2 (or somesuch).

If you want portability you don't try to compute  INT_MAX << 1  in the
first place.  This is what the entire discussion has been about.

Incidentally, (long) INT_MAX * 2 also isn't portable.  For example, int
and long might both be 96 bits, and multiplying by 2 might overflow.
But in this discussion, no one's been trying to get a long out of this.
--
Norman Diamond       diamond@jit081.enet.dec.com
If this were the company's opinion, I wouldn't be allowed to post it.
"It's been a lovely recession."
From: pjh@cs.tut.fi (Haavisto Petri)
Newsgroups: comp.std.c
Subject: Re: (long) x and (long) floor(x)
Date: 15 Dec 1992 07:14:35 GMT
Organization: Tampere University of Technology
Distribution: world
NNTP-Posting-Host: cs.tut.fi

In article <1ghtanINNcf9@cs.tut.fi> pjh@cs.tut.fi (Haavisto Petri) writes:

>I don't have the standard, but it seems clear to me that given an
>expression of type double with a positive value, the following
>should always be true:
>
>		(long) (expression) == (long) floor(expression)

Thank you for all those who answered (both privately and in the net).
As I thought, there's no excuse for the compiler. The problem was not
merely academic since the bug makes the Julian Day Number functions
given in Numerical Recipes in C (and in many other places) subtly fail.

Petri Haavisto

PS. Since there was considerable interest I will post a short program
reproducing the bug:
---
/* Demonstrate a feature of Microsoft C v6.00 (MS-DOS) involving
   conversion from double to long.
   (Compiler switches: /W3 /AL /G2 /FPi87, no other switches tried). */

#include <stdio.h>
#include <math.h>

#define N1 2415080L
#define N2 1867216.25
#define N3 36524.25

long v1(long l) { return (long) ((l - N2) / N3);}
long v2(long l) { return (long) floor((l - N2) / N3);}

int main(void)
{
  printf(" Version 1: %ld\n Version 2: %ld\n", v1(N1), v2(N1));
  return 0;
}
---
This prints:

 Version 1: 14
Newsgroups: comp.std.c
From: peterc@suite.sw.oz.au (Peter Chubb)
Subject: Assignment operator and volatile
Organization: Softway Pty Ltd
Date: Sun, 13 Dec 92 21:57:52 GMT


In the ISO standard, section 6.3.16, semantics, it states:
	An assignment expression has the value of the left operand
	after the assignment.
My question is, how soon after the assignment?

If I write code that looks like this:

#define	ap	((volatile char *)0x1234)

...
	*ap = *ap = 1;

(where the char at 0x1234 may be write-only, and return garbage when read,)
should a strictly conforming compiler generate a read instruction
after its write instruction, or can it assume that immediately after
the assignment, the char has the value 1?

	I.e., in 68000 code, 

	move.l	#$1234,a0
	move.b	#1,d0
	move.b	d0,(a0)
	move.b	(a0),d0	<-- Is this instruction necessary?
	move.b	do,(a0);

I would hope that the marked instruction is NOT necessary: if the
phrase `after the assignment' can be interpreted to mean `immediately
after the assignment' it is not; other wise, it is.


			Regards,

				- Peter Chubb

Softway Pty Ltd, P.O. Box 305, Strawberry Hills, NSW 2012, AUSTRALIA
Phone: +61 2 698 2322;       Fax: +61 2 699 9174;     Telex: AA27987
Internet: peterc@softway.oz.au	   UUCP: ...!uunet!softway.oz!peterc
Newsgroups: comp.std.c
From: sja@snakemail.hut.fi (Sakari Jalovaara)
Subject: Re: <iso646.h>
Organization: Helsinki University of Technology, Finland
Date: 16 Dec 92 07:06:15 GMT


Jeez, Doug, for a second there I actually believed you were seriously
suggesting people should use `not' for `!'.  But are those digraphs
really going to be suggested to be added to C?

jfw@ksr.com (John F. Woods):
> the "difficult" characters don't need to have the same representations
> between implementations (and may well not, in an environment where
> national characters have gobbled up the ASCII values for the
> "difficult" characters).

Does anyone, anywhere on the world know of a serious implementation of
C that uses mostly ASCII but doesn't recognize the value 0x7b as left
brace?  (Totally regardless of what that character looks like on a
terminal - on mine, it looks like an 'a' with two dots; compilers have
*no* problems with that.)

A language standard simply should not concern itself with what
characters look like on various terminals.  The "national characters
need trigraphs" argument is just plain WRONG.

> Of course, why it was necessary to do violence to the language in
> order to avoid having an occasional tape accompanied by a
> handwritten note and/or a quickie conversion utility has escaped
> many people...

Exactly!  The C standard could even have required C systems to be able
to process ASCII source code; whether that is implemented by the native
character set, as a compiler option, or as a separate program, is up to
the implementation.  As is the exact key sequence required to enter a
"left brace" token (even if it is ??( or $$( and displays as three
characters on some terminals!)

Trigraphs are BAD and UNNECESSARY.
Digraphs are WORSE and UNNECESSARY.
									++sja
From: smee@bristol.ac.uk (Paul Smee)
Newsgroups: comp.std.c
Subject: Re: Is INT_MAX<<1 defined?
Date: 17 Dec 92 15:03:12 GMT
Reply-To: P.Smee@bristol.ac.uk (Paul Smee)
Organization: University of Bristol

In article <71790001@hplvec.LVLD.HP.COM> boyne@hplvec.LVLD.HP.COM (Art Boyne) writes:
>In comp.std.c, dik@cwi.nl (Dik T. Winter) writes:
>
>>   What it comes down to is that << is not a mathematical operation, there
>>   is nothing in mathematics that tells us that 16384 << 1 equals 32768.
>>   So what is the meaning of:
>
>I'm not so sure about that.  Conceptually, the common-usage interpretation
>of the operation a << b can be represented mathematically as a*(2^b).

Umm, not necessarily on a machine using sign-magnitude representation.
Not on a twos-complement machine if the shift ends up changing the
value of the leftmost bit, even if the register does not overflow.  Not
on a ones-complement machine (are there still any of those?) if a is
negative, when the effective operation becomes a*(2^b)-1.

>Given that potential implementation, it is easy to imagine that INT_MAX << 1
>would generate overflow on such a machine.  Now, considering that the ANSI
>standard in general places as few restrictions as possible on implementations
>so as to maximize performance, I'm not sure that there is anything in the
>standard that would judge this implementation as non-conforming.

Well, OK, sod the standard for a lark, then. :-)  Let's look at K&R 1:
'The value of E1<<E2 is E1 (interpreted as a bit pattern) left-shifted
E2 bits.'  I would claim that any 'old' C programmer will expect that
behaviour.  I (and I suspect most 'oldies') would neither buy nor
recommend any C compiler which generated an exception condition for any
'valid' shift  (i.e. E2 positive, and less than the length of E1).  If
I want multiplication by a power of two with an exception on overflow,
I will WRITE a*(2^b).  Maybe market forces will win.

-- 
Paul Smee, Computing Service, University of Bristol, Bristol BS8 1UD, UK
 P.Smee@bristol.ac.uk - ..!uunet!uknet!bsmail!p.smee - Tel +44 272 303132
Newsgroups: comp.std.c
From: hoesel@igc.ethz.ch (Frans van Hoesel)
Subject: typedef void (*generic)()
Organization: University of Groningen, the Netherlands
Date: Wed, 16 Dec 1992 17:27:48 GMT

Hi,  

I have a problem in doing what I want to do in c.

a smaal exaplme
#include <stdio.h>
#include <stdlib.h>

typedef void (*generic)();

main() {
        generic f,g;
        int     i;
        f = (generic) printf;
        g = (generic) abs;

	i=-4;

	/* and now do something like :printf("some text %d\n",abs(i)
	  ), but using f and g instead !*/
}
This isn't the right group to ask (I know), but propably the best
There is also a remark from my compiler on some constructs stating that void pointer cannot be cast to function pointers. Is this allowed?

-- frans


-- 
      ================================================================
      ===  frans van hoesel               hoesel@igc.ethz.ch       ===
      ================================================================