⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hard-params.c

📁 这是完整的gcc源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* Everything you wanted to know about your machine and C compiler,   but didn't know who to ask.   Author: Steven Pemberton, CWI, Amsterdam; steven@cwi.nl   Bugfixes and upgrades gratefully received.   Name changed to `hard-params' by Richard Stallman, April 89.   xmalloc function defined, Richard Stallman, June 89.   Avoid macro in #include, Richard Stallman, Jan 90.   Undef CHAR_BIT, etc., if defined in stdio.h, Richard Stallman, Aug 90.   In EPROP, don't compare a with old if bad is already set.  Stallman, May 91.   Don't handle long doubles if -DNO_LONG_DOUBLE.  Stallman, May 91.   Copyright (c) 1988, 1989 Steven Pemberton, CWI, Amsterdam.   All rights reserved.   COMPILING   With luck and a following wind, just the following will work:	cc hard-params.c -o hard-params   If your compiler doesn't support:		add flag:	signed char (eg pcc)			-DNO_SC	unsigned char				-DNO_UC	unsigned short and long			-DNO_UI	signal(), or setjmp/longjmp()		-DNO_SIG   Try it first with no flags, and see if you get any errors - you might be   surprised. (Most non-ANSI compilers need -DNO_SC, though.)   Some compilers need a -f flag for floating point.   Don't use any optimisation flags: the program may not work if you do.   Though "while (a+1.0-a-1.0 == 0.0)" may look like "while(1)" to an   optimiser, to a floating-point unit there's a world of difference.   Some compilers offer various flags for different floating point   modes; it's worth trying all possible combinations of these.   Add -DID=\"name\" if you want the machine/flags identified in the output.   SYSTEM DEPENDENCIES   You may possibly need to add some calls to signal() for other sorts of   exception on your machine than SIGFPE, and SIGOVER.  See lines beginning   #ifdef SIGxxx in main() (and communicate the differences to me!).   If your C preprocessor doesn't have the predefined __FILE__ macro, and   you want to call this file anything other than hard-params.c, change the   #define command for __FILE__ accordingly.  If it doesn't accept macro   names at all in #include lines, order a new C compiler. While you're   waiting for it to arrive, change the last #include in this file (the   last but one line) accordingly.   OUTPUT   Run without argument to get the information as English text.  If run   with argument -l (e.g. hard-params -l), output is a series of #define's for   the ANSI standard limits.h include file, excluding MB_MAX_CHAR.  If run   with argument -f, output is a series of #define's for the ANSI standard   float.h include file.  Flag -v gives verbose output: output includes the   English text above as C comments.  The program exit(0)'s if everything   went ok, otherwise it exits with a positive number, telling how many   problems there were.   VERIFYING THE COMPILER   If, having produced the float.h and limits.h header files, you want to   verify that the compiler reads them back correctly (there are a lot of   boundary cases, of course, like minimum and maximum numbers), you can   recompile hard-params.c with -DVERIFY set (plus the other flags that you used   when compiling the version that produced the header files).  This then   recompiles the program so that it #includes "limits.h" and "float.h",   and checks that the constants it finds there are the same as the   constants it produces. Run the resulting program with hard-params -fl.  As of   this writing, of 21 compiler/flags combinations only 1 compiler has   passed without error! (The honour goes to 'pcc' on an IBM RT.)   You can also use this option if your compiler already has both files,   and you want to confirm that this program produces the right results.   TROUBLE SHOOTING.   This program is now quite trustworthy, and suspicious and wrong output   may well be caused by bugs in the compiler, not in the program (however   of course, this is not guaranteed, and no responsibility can be   accepted, etc.)   The program only works if overflows are ignored by the C system or   are catchable with signal().   If the program fails to run to completion (often with the error message   "Unexpected signal at point x"), this often turns out to be a bug in the   C compiler's run-time system. Check what was about to be printed, and   try to narrow the problem down.   Another possible problem is that you have compiled the program to produce   loss-of-precision arithmetic traps. The program cannot cope with these,   and you should re-compile without them. (They should never be the default).   Make sure you compiled with optimisation turned off.   Output preceded by *** WARNING: identifies behaviour of the C system   deemed incorrect by the program. Likely problems are that printf or   scanf don't cope properly with certain boundary numbers.  For each float   and double that is printed, the printed value is checked that it is   correct by using sscanf to read it back.  Care is taken that numbers are   printed with enough digits to uniquely identify them, and therefore that   they can be read back identically. If the number read back is different,   the program prints a warning message. If the two numbers in the warning   look identical, then printf is more than likely rounding the last   digit(s) incorrectly.  To put you at ease that the two really are   different, the bit patterns of the two numbers are also printed.  The   difference is very likely in the last bit.  Many scanf's read the   minimum double back as 0.0, and similarly cause overflow when reading   the maximum double.  The program quite ruthlessly declares all these   behaviours faulty.   The warning that "a cast didn't work" refers to cases like this:      float f;      #define C 1.234567890123456789      f= C;      if (f != (float) C) printf ("Wrong!");   A faulty compiler will widen f to double and ignore the cast to float,   and because there is more accuracy in a double than a float, fail to   recognise that they are the same. In the actual case in point, f and C   are passed as parameters to a function that discovers they are not equal,   so it's just possible that the error was in the parameter passing,   not in the cast (see function Validate()).   For ANSI C, which has float constants, the error message is "constant has   wrong precision".   REPORTING PROBLEMS   If the program doesn't work for you for any reason that can't be   narrowed down to a problem in the C compiler, or it has to be changed in   order to get it to compile, or it produces suspicious output (like a very   low maximum float, for instance), please mail the problem and an example   of the incorrect output to steven@cwi.nl or mcvax!steven.uucp, so that   improvements can be worked into future versions; mcvax/cwi.nl is the   European backbone, and is connected to uunet and other fine hosts.   This version of the program is the first to try to catch and diagnose   bugs in the compiler/run-time system. I would be especially pleased to   have reports of failures so that I can improve this service.   I apologise unreservedly for the contorted use of the preprocessor...   THE SMALL PRINT   You may copy and distribute verbatim copies of this source file.   You may modify this source file, and copy and distribute such   modified versions, provided that you leave the copyright notice   at the top of the file and also cause the modified file to carry   prominent notices stating that you changed the files and the date   of any change; and cause the whole of any work that you distribute   or publish, that in whole or in part contains or is a derivative of   this program or any part thereof, to be licensed at no charge to   all third parties on terms identical to those here.   If you do have a fix to any problem, please send it to me, so that   other people can have the benefits.   While every effort has been taken to make this program as reliable as   possible, no responsibility can be taken for the correctness of the   output, or suitability for any particular use.   ACKNOWLEDGEMENTS   Many people have given time and ideas to making this program what it is.   To all of them thanks, and apologies for not mentioning them by name.*/#ifndef __FILE__#define __FILE__ "hard-params.c"#endif#ifndef PASS#define PASS 1#define PASS1 1#define VERSION "4.1"/* Procedure just marks the functions that don't return a result */#ifdef Procedure#undef Procedure#endif#define Procedure#define Vprintf if (V) printf/* stdc is used in tests like if (stdc) */#ifdef __STDC__#define stdc 1#else#define stdc 0#endif/* volatile is used to reduce the chance of optimisation,   and to prevent variables being put in registers (when setjmp/longjmp   wouldn't work as we want)  */#ifndef __STDC__#define volatile static#endif#include <stdio.h>/* Kludge around the possiblity that <stdio.h> includes <limits.h> */#ifdef CHAR_BIT#undef CHAR_BIT#undef CHAR_MAX#undef CHAR_MIN#undef SCHAR_MAX#undef SCHAR_MIN#undef UCHAR_MAX#undef UCHAR_MIN#endif#ifdef VERIFY#include "limits.h"#include "float.h"#endif#ifdef NO_SIG  /* There's no signal(), or setjmp/longjmp() */	/* Dummy routines instead */	int lab=1;	int setjmp(lab) int lab; { return(0); }	signal(i, p) int i, (*p)(); {}#else#include <signal.h>#include <setjmp.h>	jmp_buf lab;	overflow(sig) int sig; { /* what to do on overflow/underflow */		signal(sig, overflow);		longjmp(lab, 1);	}#endif /*NO_SIG*/#define Unexpected(place) if (setjmp(lab)!=0) croak(place)int V= 0,	/* verbose */    L= 0,	/* produce limits.h */    F= 0,	/* produce float.h  */    bugs=0;	/* The number of (possible) bugs in the output */char co[4], oc[4]; /* Comment starter and ender symbols */int bits_per_byte; /* the number of bits per unit returned by sizeof() */#ifdef TEST/* Set the fp modes on a SUN with 68881 chip, to check that different   rounding modes etc. get properly detected.   Compile with additional flag -DTEST, and run with additional parameter   +hex-number, to set the 68881 mode register to hex-number*//* Bits 0x30 = rounding mode: */#define ROUND_BITS	0x30#define TO_NEAREST	0x00#define TO_ZERO		0x10#define TO_MINUS_INF	0x20#define TO_PLUS_INF	0x30 /* The SUN FP user's guide seems to be wrong here *//* Bits 0xc0 = extended rounding: */#define EXT_BITS	0xc0#define ROUND_EXTENDED	0x00#define ROUND_SINGLE 	0x40#define ROUND_DOUBLE	0x80/* Enabled traps: */#define EXE_INEX1  0x100#define EXE_INEX2  0x200#define EXE_DZ	   0x400#define EXE_UNFL   0x800#define EXE_OVFL  0x1000#define EXE_OPERR 0x2000#define EXE_SNAN  0x4000#define EXE_BSUN  0x8000printmode(new) unsigned new; {	fpmode_(&new);	printf("New fp mode:\n");	printf("  Round toward ");	switch (new & ROUND_BITS) {	      case TO_NEAREST:   printf("nearest"); break;	      case TO_ZERO:      printf("zero"); break;	      case TO_MINUS_INF: printf("minus infinity"); break;	      case TO_PLUS_INF:  printf("plus infinity"); break;	      default: printf("???"); break;	}	printf("\n  Extended rounding precision: ");	switch (new & EXT_BITS) {	      case ROUND_EXTENDED: printf("extended"); break;	      case ROUND_SINGLE:   printf("single"); break;	      case ROUND_DOUBLE:   printf("double"); break;	      default: printf("???"); break;	}	printf("\n  Enabled exceptions:");	if (new & (unsigned) EXE_INEX1) printf(" inex1");	if (new & (unsigned) EXE_INEX2) printf(" inex2");	if (new & (unsigned) EXE_DZ)    printf(" dz"); 	if (new & (unsigned) EXE_UNFL)  printf(" unfl"); 	if (new & (unsigned) EXE_OVFL)  printf(" ovfl"); 	if (new & (unsigned) EXE_OPERR) printf(" operr"); 	if (new & (unsigned) EXE_SNAN)  printf(" snan"); 	if (new & (unsigned) EXE_BSUN)  printf(" bsun"); 	printf("\n");}int setmode(s) char *s; {	unsigned mode=0, dig;	char c;	while (*s) {		c= *s++;		if  (c>='0' && c<='9') dig= c-'0';		else if (c>='a' && c<='f') dig= c-'a'+10;		else if (c>='A' && c<='F') dig= c-'A'+10;		else return 1;		mode= mode<<4 | dig;	}	printmode(mode);	return 0;}#elseint setmode(s) char *s; {	fprintf(stderr, "Can't set mode: not compiled with TEST\n");	return(1);}#endifcroak(place) int place; {	printf("*** Unexpected signal at point %d\n", place);	exit(bugs+1); /* An exit isn't essential here, but avoids loops */}/* This is here in case alloca.c is used.  That wants to call this.  */char *xmalloc(size) unsigned size; {	char *malloc();	char *value = malloc(size);	if (value == 0) {		fprintf(stderr, "Virtual memory exceeded\n");		exit(bugs+1);	}	return value;}main(argc, argv) int argc; char *argv[]; {	int dprec, fprec, lprec, basic(), fprop(), dprop(), efprop(), edprop();	char *malloc();	unsigned int size;	long total;	int i; char *s; int bad;#ifdef SIGFPE	signal(SIGFPE, overflow);#endif#ifdef SIGOVER	signal(SIGOVER, overflow);#endif/* Add more calls as necessary */	Unexpected(1);	bad=0;	for (i=1; i < argc; i++) {		s= argv[i];		if (*s == '-') {			s++;			while (*s) {				switch (*(s++)) {				      case 'v': V=1; break;				      case 'l': L=1; break;				      case 'f': F=1; break;				      default: bad=1; break;				}			}		} else if (*s == '+') {			s++;			bad= setmode(s);		} else bad= 1;	}	if (bad) {		fprintf(stderr,			"Usage: %s [-vlf]\n  v=Verbose l=Limits.h f=Float.h\n",			argv[0]);		exit(1);	}	if (L || F) {		co[0]= '/'; oc[0]= ' ';		co[1]= '*'; oc[1]= '*';		co[2]= ' '; oc[2]= '/';		co[3]= '\0'; oc[3]= '\0';	} else {		co[0]= '\0'; oc[0]= '\0';		V=1;	}	if (L) printf("%slimits.h%s\n", co, oc);	if (F) printf("%sfloat.h%s\n", co, oc);#ifdef ID	printf("%sProduced on %s by hard-params version %s, CWI, Amsterdam%s\n",	       co, ID, VERSION, oc);#else	printf("%sProduced by hard-params version %s, CWI, Amsterdam%s\n",	       co, VERSION, oc);#endif#ifdef VERIFY	printf("%sVerification phase%s\n", co, oc);#endif#ifdef NO_SIG	Vprintf("%sCompiled without signal(): %s%s\n",		co,		"there's nothing that can be done if overflow occurs",		oc);#endif#ifdef NO_SC	Vprintf("%sCompiled without signed char%s\n", co, oc);#endif#ifdef NO_UC	Vprintf("%Compiled without unsigned char%s\n", co, oc);#endif#ifdef NO_UI	Vprintf("%Compiled without unsigned short or long%s\n", co, oc);#endif#ifdef __STDC__	Vprintf("%sCompiler claims to be ANSI C level %d%s\n",		co, __STDC__, oc);#else	Vprintf("%sCompiler does not claim to be ANSI C%s\n", co, oc);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -