[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference turris::decc

Title:DECC
Notice:General DEC C discussions
Moderator:TLE::D_SMITHNTE
Created:Fri Nov 13 1992
Last Modified:Fri Jun 06 1997
Last Successful Update:Fri Jun 06 1997
Number of topics:2212
Total number of notes:11045

2102.0. "DECC and source from another system(RS6000)" by DEKVC::JUNMOKSONG () Fri Feb 21 1997 02:54

    
     How are you?
    
     From HP and RS600 I got source program as following:
     And Compile is O.K but when i run a.out, Memory fault(coredump)
     happened. Can anyone help me?
    
     Best Regards,
     Jun-Mok Song
    
-------------------------------------------------------------------------------
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void err(); 

main()
{
	err(__FILE__,__LINE__,"single");
	err(__FILE__,__LINE__,"single","Duo");
	err(__FILE__,__LINE__,"(%d) %s %s", 999, "single", "Duo");
}

void err (file,line, fmt, A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U)
	char *file, *fmt;
	int line;
{
	FILE *ft;
	char fmt1[1024],fmt2[1024],efile[100],date[20],time[20];
	                   
	strcpy(fmt1, "%s");
	strcat(fmt1, fmt);
        sprintf(fmt2, fmt1, "",A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U);
	sprintf(fmt1,"%s[%d]:%s", file, line, fmt2);
	fprintf(stderr, "%s\n");
	return;

}
-------------------------------------------------------------------------------
T.RTitleUserPersonal
Name
DateLines
2102.164 bit porting problemMUCTEC::BECKERHartmut B., VMS &amp; Languages, MunichFri Feb 21 1997 04:4410
In your example you left out the fmt1 argument in the fprintf call. But
that's not the problem. Your (or his) example works in a 32 bit
environment, it doesn't in a 64 bit environment. The call to err passes
strings where err expect ints. Adresses are 64 bit long, ints are 32 bit
long, they don't match. As a temporary solution you might want to use
-taso. It works as expected for your example but you might want to make
your code 64 bit clean.

Hope this helps,
Hartmut
2102.2Better workaroundWIBBIN::NOYCEPulling weeds, pickin&#039; stonesFri Feb 21 1997 10:159
Does that mean it would help to add this line to err?

void * A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U;

(or char * should work as well, in case some compilers don't like it.)

Nevertheless, this is not a valid C program, since you call a function
with a different number of arguments than what it is declared to take,
and you don't use the varargs mechanism.
2102.3Try stdarg and vsprintfDECCXL::WIBECANThat&#039;s the way it is, in Engineering!Fri Feb 21 1997 10:1746
>> In your example you left out the fmt1 argument in the fprintf call. But
>> that's not the problem.

Well, it is the problem in that it causes the seg fault on the first call to
err().  But it isn't the only problem, as you point out.

>> Your (or his) example works in a 32 bit
>> environment, it doesn't in a 64 bit environment. The call to err passes
>> strings where err expect ints. Adresses are 64 bit long, ints are 32 bit
>> long, they don't match. As a temporary solution you might want to use
>> -taso. It works as expected for your example but you might want to make
>> your code 64 bit clean.

To give a little more detail, the unspecified arguments to err are defaulting
to int.  You are actually passing char pointers, and sprintf and fprintf are
expecting char pointers.  The conversion to int is dropping the high 32 bits.

You might want to re-code this using a full prototype for err() with "..."
format, use stdarg to handle the argument list, and use vsprintf instead of
sprintf for the first sprintf call.  Something like this:

#include <stdarg.h>

[other #include directives and code for main() omitted]

void err (char *file, int line, char *fmt, ...)
{
        FILE *ft;
        char fmt1[1024],fmt2[1024],efile[100],date[20],time[20];
        va_list ap;

        sprintf(fmt1, "%s%s", "", fmt);
		/*
		** Merged strcpy, strcat, and part of first sprintf call
		** into a single sprintf.  I wasn't sure what the purpose
		** of the sprintf of "" into fmt2 was.  You could consider
		** dropping it if it is always a null string.
		*/
        va_start (ap, fmt);		/* Set up variable arg access */
        vsprintf(fmt2, fmt1, ap);	/* Like sprintf but with var args */
        va_end (ap);			/* Done with variable arg access */
        sprintf(fmt1,"%s[%d]:%s", file, line, fmt2);
        fprintf(stderr, "%s\n",fmt1);
        return;

}
2102.4Wrong is wrong...DECC::SULLIVANJeff SullivanFri Feb 21 1997 12:1618
As the previous replies stated, the code in the base note is and was always
incorrect. It just so happened to work on other (inferior) operating systems.
Brian's suggestion in .3 is a good one. That is, you should always use stdargs
for variable argument functions.

There are a couple of pages that describe stdargs (recommended for ANSI C) and
varargs (supported for K&R) at the Cygnus website.

See
http://www.cygnus.com/pubs/gnupro/5_libraries/b_libc/libchtmlANSIstandard_macros
_stdargh.html

and

http://www.cygnus.com/pubs/gnupro/5_libraries/b_libc/libchtmlTraditional_macros_
varargsh.html

-Jeff
2102.5unfortunately: wrong is validMUCTEC::BECKERHartmut B., VMS &amp; Languages, MunichFri Feb 21 1997 15:418
The program is valid and it's not wrong in terms of ANSI C. It simply exploits
the lack of a proper data model in C. And the data model changes if you go from
the inferior operating system to the superior one.

That it is poor programming style and that it is a poor algorithm for variable
arguments is the other side of the coin.

Hartmut
2102.6The program is only valid if you consider undefined behavior valid.CXXC::REPETERich Peterson 381-1802 ZKO2-3/N30Fri Feb 21 1997 17:2826
RE .5:

> The program is valid and it's not wrong in terms of ANSI C.

It might arguably be considered sort of valid under K&R C in
the sense that K&R first edition is completely silent on the
subject of what happens when you have a function call with
a different number of arguments than the number of formal
parameters in its definition, and that this style was more
or less common practice before the invention of varargs.h.

But it is quite clearly designated as having undefined behavior
under ANSI C 3.3.2.2 (ISO 6.3.2.2) "Functions calls":

  "If the expression that denotes the called function has a type that
   does not include a prototype, the integral promotions...  If the
   number of arguments does not agree with the number of parameters,
   the behavior is undefined."

RE .2:

> void * A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U;

This meant to say:

void *A,*B,*C,*D,*E,*F,*G,*H,*I,*J,*K,*L,*M,*N,*O,*P,*Q,*R,*S,*T,*U;