HDTenEightyP/NetNews huggingface dataset:
From: lwv26@cas.org (Larry W. Virden)
Subject: How do I portably code a function to be vararg?
Reply-To: lvirden@cas.org (Larry W. Virden)
Organization: Nedriv Software and Shoe Shiners, Uninc.
Date: Tue, 1 Sep 1992 19:30:49 GMT

I have a function which will need to compile under ANSI and pre-ANSI compilers.
In all environments, there are varargs.h - in at least one there is no 
stdarg.h

What would be the Politically Correct method of coding this?
-- 
Larry W. Virden                 UUCP: osu-cis!chemabs!lvirden
Same Mbox: BITNET: lvirden@cas  INET: lvirden@cas.org
Personal: 674 Falls Place,   Reynoldsburg, OH 43068-1614
America Online: lvirden@aol.com
Newsgroups: comp.lang.c
From: hp@vmars.tuwien.ac.at (Peter Holzer)
Subject: Re: Why should POINTERS be so damn hard to understand ?
Organization: Technical University Vienna, Dept. for Realtime Systems, AUSTRIA
Date: Thu, 27 Aug 1992 18:18:44 GMT

barmar@think.com (Barry Margolin) writes:

>for (_i=(char *)a; _i<a+1000*sizeof(int); _i+=sizeof(int))
>    *(int *)_i = whatever();

>I would epect this to produce almost identical code.  And in a language
>where pointers weren't typed, you wouldn't need all the casting.

You would still have to cast _i to (int *), or the compiler couldn't
know how much memory it should access (1 byte? 1 word? ...)

Anyway, why should I type sizeof(int), when the compiler can do it for
me?

-- 
|    _  | Peter J. Holzer                       | Think of it   |
| |_|_) | Technical University Vienna           | as evolution  |
| | |   | Dept. for Real-Time Systems           | in action!    |
| __/   | hp@vmars.tuwien.ac.at                 |     Tony Rand |
From: ugo@oliver.sublink.org (Ugo Cei)
Newsgroups: comp.lang.c
Subject: Re: general tree
Date: 29 Aug 92 09:34:12 GMT
Organization: Oliver System - Pavia ITALY

dpm@wizard.b29.ingr.com (David Mikesell) writes:

>I am beginning work on a C program that will manipulate a general tree, i.e.
>a tree in which each node can have an arbitrary number of children.  An ex-
>ample declaration of the structure follows:

There is a simple way to map general trees to binary trees which works
quite well. Since binary trees are much easier to deal with and to find
adequate representations for, this might indeed help you. Here it
goes:

- the root of the binary tree is the same as the root of the n-ary
  tree;
- left child of a node of the binary tree corresponds to the first
  child of the same node in the n-ary tree;
- right child of a node in the binary tree corresponds to the sibling
  immediately to the right of that node in the n-ary tree.

This is an example of this mapping:

          A                      A
        / | \                   /
       B  C  D          -->    B
       |    / \               / \
       E   F   G             E   C
                                  \
                                   D
                                  /
                                 F
                                 \
                                  G

Note that:

- the root, having no siblings, has no right subtree;
- leaf nodes have no left subtree, but might have a right subtree if
  they have at least one sibling to their right.

You can retrieve data from the binary tree in this way:

- if you intend to do a pre-order traversal of the n-ary tree (i.e.
  first visit the parent, then the children of any subtree), do a
  pre-order traversal of the binary tree. Looking at the example,
  nodes are retrieved in this order: A B E C D F G.
- if you intend to do a post-order traversal (i.e., first visit
  subtree, then root), do a symmetrical-order traversal of the binary
  tree (i.e. first visit left subtree, then root, then right subtree).
  In this latter case, nodes are retrieved in this order: E B C F G D A.

	Hope this helps,
				Ugo

-- 
Ugo Cei --- Via Colombo 7 - 27100 Pavia - ITALY   |
         -- Sublink:  ugo@oliver.sublink.org      | "Real programs dump core"
Newsgroups: comp.lang.c
From: drice@ponder.csci.unt.edu (Keith Rice)
Subject: Re: Most difficult part of learning C?
Organization: University of North Texas
Distribution: usa
Date: Wed, 26 Aug 1992 23:41:09 GMT


goldstei@cgi.com ("Morris Goldstein") writes:

>I am conducting research for a little project concerning difficulties in
>learning C and how to improve the teaching of C so as to circumvent these
>problems.

>When learning C, what things did you find the most confussing/difficult to
>understand?

>        -Morris

>(goldstein@cgi.com)

Understanding and using pointers.

--
Keith
drice@ponder.csci.unt.edu

Newsgroups: comp.lang.c
From: steve@taumet.com (Steve Clamage)
Subject: Re: Simple C question
Organization: TauMetric Corporation
Date: Tue, 25 Aug 1992 16:39:34 GMT

sj@cs.brown.edu (Shuang Ji) writes:

>In article <760a5705@p3.f6.n249.z2.fidonet.org>, Gilles_Kohl@spam.fido.de (Gilles Kohl) writes:
>|>  > main()
>|> 
>|>  > {
>|>  >  char s[] = "Hello world!" ;
>|>  > }

>Variables declared as "char s[]" are not considered to be left values. And in fact,
>the value of the string "Hello world" is the address of this staticly stored 
>string. So this initialization is illegal.

No, it is legal (but see below).  There is a special dispensation for
literal strings used to initialize arrays of char.  For this purpose
only, "hello" is considered a shorthand for {'h','e','l','l','o','\0'}.
Thus, both of these are legal, but mean different things:
	char *p  = "hello";
	char s[] = "hello";
The first initializes 'p' to point to an anonymous array of chars
containing "hello" (plus a null), and the second defines 's' to be an
array of 6 chars containing "hello" (plus a null).

Pre-Standard compilers typically did not allow initialization of
aggregate auto variables, but only those of with static storage duration.
A Standard compiler allows initialization of auto aggregates, as above.
-- 

Steve Clamage, TauMetric Corp, steve@taumet.com
Vice Chair, ANSI C++ Committee, X3J16
Newsgroups: comp.lang.c,comp.std.c
From: msb@sq.sq.com (Mark Brader)
Subject: Re: strcpy implementation question
Organization: SoftQuad Inc., Toronto, Canada
Date: Tue, 25 Aug 92 17:04:33 GMT

In articles whose Distribution lines are invalid (don't do that!),
John R. Levine (johnl@iecc.cambridge.ma.us) writes:

> > In my copy of the C standard, section 4.1.1 says "a string is a contiguous
> > sequence of characters terminated by and including the first null
> > character."  Section 4.11.2.3 says "The strcpy function copies the string
> > pointed to by s2 (including the terminating null character) into the array
> > pointed to by s1."
> > 
> > But it doesn't say "(including the terminating null character and any other
> > garbage convenient for the compiler implementer)".  You have to stop at the
> > null byte.

And Bob Balkwill (balkwill@ncs.dnd.ca) replies:

> Sorry - but one cannot assume more than the C std declares.  Maybe old
> ill-advised code will break, but what happens after the null byte is up for
> grabs. ...

However, one can assume *as much* as the standard declares.

As I said in email to the original poster, the standard also does not say
that strcpy() doesn't write "Mark is an idiot\n" to stdout.  It doesn't have
to!  [Er, I mean that the standard doesn't have to say that, not that
strcpy() doesn't have to write that. :-)]  The descriptions in part 4 of
the standard tell *everything* that the functions are supposed to do.

The string is terminated by the null character, and copying any more is
an error.  John is right.  In my educated opinion.
-- 
Mark Brader			"A clarification is not to make oneself clear.
SoftQuad Inc., Toronto		 It is to PUT oneself IN the clear."
utzoo!sq!msb, msb@sq.com		-- Lynn & Jay, "Yes, Prime Minister"

This article is in the public domain.
Newsgroups: comp.lang.c
From: atbowler@thinkage.on.ca (Alan Bowler)
Subject: Re: ANSI description for signal handling
Organization: /etc/organization
Date: Wed, 2 Sep 1992 00:20:21 GMT

In article <1804biINN944@early-bird.think.com> barmar@think.com (Barry Margolin) writes:
>In article <1992Sep1.020305.15064@thinkage.on.ca> atbowler@thinkage.on.ca (Alan Bowler) writes:
>>  In the case of an implicit raise,
>>you can only call signal() with the SAME signal number, and you can
>>only get out of the handler by doing a return.
>
>But the quoted passage also says that if you do a return from a handler
>that was called due to SIGFPE, the behavior is undefined.  So, if SIGFPE is
>raised implicitly, there's no way to get out of the handler!

I interpreted that passage to mean that the result from the computation
that caused the SIGFPE was undefined.  However, you are right, and the
standard does not guarantee that you can not rely on returning
from from a signal raised implicitly due to a computational exception.
Presumably this is so that systems with imprecise interrupts are not
overly constrained.  

You will have to check what your implementation does with signals from
computational exceptions, and what it defines as the rules.  It is
likely (but not guarenteed), that you can longjmp out of these
execptions, since they should not be occuring inside the library.
Trying to handle computional faults is one of those things that is by
its nature system dependant, and so is part of the code that will need
to be tweeked when porting a program.

In most cases the "portable" thing to do is to arrange that SIGFPE and
other computional exceptions don't occur.  For most programs this boils
down to not dividing by zero.
Newsgroups: comp.lang.c
From: scipio@milton.u.washington.edu (jim lee)
Subject: random number generation
Organization: University of Washington, Seattle
Date: Thu, 27 Aug 1992 13:38:05 GMT

Can someone help me?  I need some coding that will generate random
numbers.

Thanks for any help.


Jim Lee (scipio@u.washington.edu)
From: jos@and.nl (Jos Horsmeier)
Newsgroups: comp.lang.c
Subject: Re: printf question
Date: 30 Aug 92 14:25:57 GMT
Organization: AND Software BV Rotterdam

In article <RICHARD.92Aug30153124@CLYDE.ttt.kth.se> RICHARD@CLYDE.ttt.kth.se writes:
|In article <kimcm.714943581@login.dkuug.dk> kimcm@login.dkuug.dk (Kim Chr. Madsen) writes:
||   #define HDPI "4" /* Hex Digits Per Int */
||
||	   printf( "%0" HDPI "x\n", address );
||
||   And if you have read this far, you surely won't mind one more irrelevant
||   remark ;-)  Using this syntax on the original problem will save you some
||   time because the format is evaluated at compile time instead of run time.
|
|Huh????? Since when is the format evaluated at compile time? I've never
|seen that done!

The contents of the format string isn't evaluated at compile time but,
in this case, the pre-processor concatenates the constant strings after
macro replacement. The evaluation goes like this:

1:	   printf( "%0" HDPI "x\n", address );
2:         printf( "%0" "4" "x\n", address );
3:         printf( "%04x\n", address );

And that was exactly what the original poster had in mind; all done during
compile time ...

kind regards,

Jos aka jos@and.nl
Newsgroups: comp.lang.c
From: atbowler@thinkage.on.ca (Alan Bowler)
Subject: Re: ANSI description for signal handling
Organization: /etc/organization
Date: Tue, 1 Sep 1992 02:03:05 GMT

In article <9208311517.AB03610@ucbvax.Berkeley.EDU> JENNIFER@TOROLAB6.VNET.IBM.COM ("Jennifer Hamilton") writes:
>In the ANSI standard under the description of the signal function,
>(section 4.7.1.1) it states the following:
>
>   "The function func may terminate by executing a return statement or
>   by calling the abort, exit, or longjmp functions.  If func executes a
>   return statement and the value of sig was SIGFPE or any other
>   implementation-defined value corresponding to a computational
>   exception, the behaviour is undefined.  Otherwise, the program will
>   resume execution at the point it was interrupted.  If the signal
>   occurs other than as the result of calling the abort or raise
>   function, the behaviour is undefined if the signal handler calls any
>   function in the standard library other than the signal function
>   itself ..."
>
>The last sentence implies that you can't call any library functions
>(such as longjmp, abort or exit) from within the signal handler unless
>the signal was explicitly raised through raise or abort.  But the first
>three sentences imply that you can.  Can anyone explain this apparent
>contradiction?
>
The last sentence tells you WHEN you can use abort(), exit() or
longjmp().  The first 3 sentences tell you what happens if you do.

I.e. If the program did an explicit call to raise(), (this includes a
call to abort() ), and a signal handler is invoked as a result, then
that signal hander may call abort(), exit() and longjmp() an be assured
that they will function as they are documented.  NO such guarantee 
is given if the signal hanler is invoked as the result of an implicit
raise of the signal by the system.  In the case of an implicit raise,
you can only call signal() with the SAME signal number, and you can
only get out of the handler by doing a return.  ANSI does not give
further guarantees.  However, better implementations may very well
allow you more freedom.  However, it is very hard to write code that
will survive a longjmp() out of an asynchronous signal handler.  It is
usually much easier not to try.
From: wirzeniu@klaava.Helsinki.FI (Lars Wirzenius)
Newsgroups: comp.lang.c
Subject: Re: main()
Date: 4 Sep 92 14:37:38 GMT
Organization: University of Helsinki

mike@pacsoft.com (Mike Stefanik) writes:
>Has there been any standardization efforts in regards to the exit status
>returned by programs?  

Yes.  ANSI defined 0 (and the macro EXIT_SUCCESS) to mean success, and 1
(EXIT_FAILURE) to mean failure.  If the operating system under which the
program runs does not use the same value, then it is the C runtime
environment's problem to translate these two values in a suitable way.

Note that the conversion should be done even if the value is return via
an explicit return statement in main.  The VAX/VMS C compiler does not
seem to get this right, but then I don't think it claims to be a
standard conforming compiler, so one can't really treat it as a bug
either.

--
Lars.Wirzenius@helsinki.fi
Xref: sparky comp.lang.c:13168 comp.sys.sun.misc:4066
From: ama@metrix.UUCP (Alan Amaral)
Newsgroups: comp.lang.c,comp.sys.sun.misc
Subject: Re: sun cc optimization failure
Date: 3 Sep 92 14:43:08 GMT
Reply-To: ama@metrix.UUCP (Alan Amaral)
Organization: Matrix Computer Systems Inc.

In article <1992Sep3.040401.16902@mr.med.ge.com> carl@aslmr-serv.med.ge.com (Carl Crawford) writes:
>
>consider the following program:
>
>main() {
>	int i,j,ax;
>	ax = 0;
>	for(i=0;i<3;i++){
>		j = ax * i;
>		puts("in for loop");
>	}
>}
>when compiled with cc (sun os 4.1 on sparc 1+), the 
>code runs thru the loop three times. when comiled with 
>the -O flag it only runs once. hom come the optimization 
>screws up the loop?
>--
>Carl R. Crawford	   Voice: 414-521-6572
>GE Medical Systems	   Fax: 414-521-6575
>P.O. Box 414, W-875	   Internet: crawfordc@med.ge.com
>Milwaukee, WI 53201	   

I tried this on an ELC, running 4.1.1.  It's broken for me also.

It's the global optimization (level 2) that is screwing things up.

If you look at the assembler output of the compiler using the following
commands you'll see some wierd things in the globally optimized version:

cc -O1 -S -o foo1.s foo.c		# this works fine
cc -O2 -S -o foo2.s foo.c		# this breaks

foo2.s looks like this:

    .seg    "text"          ! [internal]
    .proc   16
    .global _main
_main:
!#PROLOGUE# 0
!#PROLOGUE# 1
    save    %sp,-96,%sp
    mov 0,%i5
    mov 0,%i3
    mov 0,%i4
    sethi   %hi(L21),%o0
LY1:                    ! [internal]
    call    _puts,1
    or  %o0,%lo(L21),%o0    ! [internal]
    add %i5,%i3,%i5
    cmp %i5,%i4
    bl,a    LY1
    sethi   %hi(L21),%o0
    ret
    restore
    .seg    "data"          ! [internal]
    .seg    "data1"         ! [internal]
L21:
    .ascii  "in for loop\0"

If you look at the register initialization (just after the PROLOGUE) it's
clear that given the values held in the registers that the "add %i5,%i3,%i5"
statement is adding 0 to 0 and then the "cmp %i5,%i4" is comparing 0 to 0.
The "bl,a LY1" then fails (0 is not less than 0), so the code doesn't loop...

"i5" is being used as the loop counter, and is initialized to 0. "i3" is
being used as the increment value, and should be 1, not 0.  "i4" is the loop
end test value, and should be 3, not 0.  It looks like the compiler should
be doing the following register initialization instead of what it's doing:

    save    %sp,-96,%sp
    mov 0,%i5
    mov 1,%i3
    mov 3,%i4

If you change the assember code to this and then assemble it then everything
works fine.  This is definitely an optimizer bug and should be reported to SUN.

It really strange that simple pieces of code like this break things, and yet
there are probably millions of lines of code out there that (seem to) work
fine with the same compiler.  Go figure...


-- 
Alan Amaral             |  Email: ama@metrix.COM
Metrix Network Systems  |  Voice: (603) 888-7000
Newsgroups: comp.lang.c
From: mjn@pseudo.uucp (Murray Nesbitt)
Subject: Re: printf question
Organization: Private system in Toronto, ON
Date: Thu, 3 Sep 1992 08:06:52 GMT
	<RICHARD.92Aug30153124@CLYDE.ttt.kth.se> <3361@dozo.and.nl>
	<1SEP199221241770@eql.caltech.edu>


rankin@eql.caltech.edu (Pat Rankin) writes:

>In article <3361@dozo.and.nl>, jos@and.nl (Jos Horsmeier) writes...
>[ quoting other articles ]
>>||   #define HDPI "4" /* Hex Digits Per Int */
>>||	   printf( "%0" HDPI "x\n", address );
>[ text deleted ]
>> in this case, the pre-processor concatenates the constant strings after
>> macro replacement.
>
>     Minor quibble:  string concatentation is performed by the compiler,
>not the preprocessor.  Since this won't work with pre-ANSI compilers, its
>use tends to reduce portability anyway.

Concatenation of character string literals is performed during the
preprocessing phase of translation.

-- 
Murray
From: quanstro@lars.StOlaf.edu (goon)
Subject: Re: Giles' Manual Mania (Was - Re: About the 'F' in RTFM)
Organization: St. Olaf College, Northfield, MN USA
	<1992Aug27.003746.8092@newshost.lanl.gov>
	<1992Sep1.185546.15682@mksol.dseg.ti.com>
	<1992Sep1.233050.7075@newshost.lanl.gov>
Date: 2 Sep 92 09:58:12

In article <1992Sep1.233050.7075@newshost.lanl.gov> jlg@cochiti.lanl.gov (Jim Giles) writes:

   [...]  I found UNIX to be unnecessarily
   complex.  I understood it (finally, after much effort), but I find it
   difficult to recommend such unnecessary pain to other users - since it
   was among the least powerful and hardest to use systems I've ever
   used.  

You are great at speaking in generalities. Which systems _have_ you
used? 

   And there  *are* simpler things with *more* power already available.  
   The only thing I have to seek are ways to attract users toward these 
   better system designs. 

Please tell us what you mean by ``power.'' This is so vague as to border
on contentless. And of which ``better system designs'' are you speaking?

   Too many of these new designs and ideas are
   let fall by the wayside because thay are not widespread standards.
   And the pro-UNIX propaganda machine is a formidable opponent. 

This is just true in general. A pro x bias (calling it a ``propaganda
machine'' goes a bit far), where x is just about anything, is hard to
overcome. There are things to be said for standards. Even if you are
right that  Unix is difficult to learn and relatively unpowerful, it's
unfortunately the case that there is good motivation (perhaps not
sufficient) for keeping the old: learning a new system is always
somewhat painful and porting old software is often next to impossible.

   A
   demonstration of the well known phenomenon in software design that
   quality and popularity are uncorrelated.

Who ever said that this was the case in any sphere? [Consider the NY
Times bestsellers list.]
Newsgroups: comp.lang.c
From: ptran@envmsa.eas.asu.edu (Phi-Long Tran)
Subject: Re: pointer to multi D array. How?
News-Software: VAX/VMS VNEWS 1.4-b1  
Organization: Arizona State University, Tempe, AZ
Date: Fri, 28 Aug 1992 15:20:00 GMT

In article <RICHARD.92Aug27181915@CLYDE.ttt.kth.se>, 
RICHARD@CLYDE.ttt.kth.se writes...
>In article <1992Aug26.050053.114348@zeus.calpoly.edu> 
clin@zeus.calpoly.edu (Chihtsung Jeffrey Lin) writes:

>> ...  How do you declare a pointer to a multi-dimensional array?  [H]ere
>> is what I did.
>> int A[5][5]:={1,2,3,......}, **x;

> Make that:
> int A[5][5]={1,2,3,.....}, *x;

     Why not make an actual pointer to an array?  It may make references
easier to code.  For example, a pointer to the array A declared above would
be, "int (*ptrA)[5][5]".  Then we could reference array A with ptrA as:

     ptrA = &A;		 /* Assign ptrA the address of array A. */
     (*ptrA)[5][0] = 1;	 /* (*ptrA) is the array A. */

The pointer to the array, as in the above, is useful for dynamically
allocating multi-dimensional arrays or changes the starting address of any
array.

---
Phi-Long Tran
ptran@asuvax.eas.asu.edu
Arizona State University
From: davis@pacific.mps.ohio-state.edu ("John E. Davis")
Newsgroups: comp.lang.c
Subject: compiler bug or (I hope) me?
Date: 3 Sep 92 01:11:02 GMT
Reply-To: davis@pacific.mps.ohio-state.edu  (John E. Davis)
Organization: "Dept. of Physics, The Ohio State University"

Hi,

    Consider the following program:

#include <stdio.h>
float fproto(float x)
{
   fprintf(stdout, "In fproto, x = %f\n", x);
   return(2.0 * x);
}

float fkr(x)
float x;
{
   fprintf(stdout, "In fkr, x = %f\n", x);
   return(2.0 * x);
}

main()
{
   float x,y;
   long f, *fp;
   
   x = 2.0;
   f = (long) fkr;
   fp = &f;
   y = ( (float (*)(float)) (*fp) )(x);
   fprintf(stdout, "from fkr: %f\n", y);
   
   x = 2.0;
   f = (long) fproto;
   fp = &f;
   y = ( (float (*)()) (*fp) )(x);   /* <<---- see text below */
   fprintf(stdout, "from proto: %f\n", y);
}

Here I have assummed that long and long * have the same size.  I have
ran this using the mips c compiler and gcc on a dec station 5000, as
well as Borland C++ 3.0 with the large memory module.  In all cases, I
obtained:

In fkr, x = 2.000000
from fkr: 4.000000
In fproto, x = 0.000000
from proto: 0.000000

What am I doing wrong? I replaced the line referenced above with 

   y = ( (float (*)(float)) (*fp) )(x);   /* <<---- see text below */

and it ran as expected when compiled under gcc and BCC++.  However, it still
refused to produce the desired results under the standard mips c compiler.
Now when I replaced the first typecase for the pointer to the unprotyped
function, as in:

   f = (long) fkr;
   fp = &f;
   y = ( (float (*float)(float)) (*fp) )(x);
   
gcc failed for this function, BCC++ produced a floating point overflow, but
the mips c compiler got it right!

Please explain this behavior to me.  I am confused because I thought that
the typecast: '(float (*)())' casts a pointer to a function of type float
with no information about its arguments. That is,

float a0();
float a1(float);
float a2(float, float);
etc....

are all of the type (float (*)()).   Stated another way, (float (*)(int)) is
a subset of (float (*)()).  Is this correct?  Compare with the BCC++ manual:
(page 55, programmers guide):

      ``...Under C++, which has stronger type checking, a pointer to a
      function has type ``pointer to function taking argument types
      `type' and returning `type'.'' In fact under C a function
      defined with argument types will also have this narrower type.
      For example:

         void (*funct)();

      In C, this is a pointer to a function returning nothing.  In
      C++, it is a pointer to a function taking no arguments and
      returning nothing....''

So, it seems to me that in C, the above program should work without the
explicitly putting (float) in the argument list of the typecast.

Any suggestions?  
--
     _____________
#___/John E. Davis\_________________________________________________________
#
# internet: davis@amy.tch.harvard.edu
#   bitnet: davis@ohstpy
#   office: 617-735-6746
#