宏展开与C语言异常处理
时间:2010-09-20 来源:idx001
宏#define NUMundefined HUGE_VAL
不知这个HUGE_VAL为何物,以为是自定义的,sourceinsight中search好久,不得。google之。
得知 HUGE_VAL乃math.h中的宏:
http://zhidao.baidu.com/question/18069565.html
math.h The math header defines several mathematic functions. Macros: HUGE_VAL Functions: acos(); asin(); atan(); atan2(); ceil(); cos(); cosh(); exp(); fabs(); floor(); fmod(); frexp(); ldexp(); log(); log10(); modf(); pow(); sin(); sinh(); sqrt(); tan(); tanh();
2.7.1 Error Conditions All math.h functions handle errors similarly. In the case that the argument passed to the function exceeds the range of that function, then the
variable errno is set to EDOM. The value that the function returns is implementation specific. In the case that the value being returned is too large to be represented in a double, then the
function returns the macro HUGE_VAL, and sets the variable errno to ERANGE to represent an
overflow. If the value is too small to be represented in a double,then the function returns zero.
In this case whether or not errno is set to ERANGE is implementation specific. errno, EDOM, and ERANGE are defined in the errno.h header. Note that in all cases when it is stated that there is no range limit, it is implied that the
value is limited by the minimum and maximum values of type double.
http://blog.chinaunix.net/u2/73528/showart_1134021.html
— Built-in Function: double __builtin_huge_val (void)
Returns a positive infinity, if supported by the floating-point format, else DBL_MAX. This function is suitable for implementing the ISO C macro HUGE_VAL.
*******************************************************************************************
宏利于代码的简化,却不利于代码的阅读,特别是遇到连接符的情况:
例如#define FUNC(x) int func_##x()
而在其他文件中定义func_开头的各种函数,使用的时候是FUNC(TEST),是很难阅读的。
可用gcc -E source 来使用gcc只做预处理操作,将文件的中的宏全部展开。
*******************************************************************************************
类似HUGE_VAL实际上可以用来作异常处理操作,即c语言实际上也可以作异常处理
http://hi.baidu.com/progressbar/blog/item/614a969bc8615c066e068cbb.html
异常处理头文件setjmp.h
#include <stdlib.h>
#include <stdio.h>
#include <setjmp.h>
#include <errno.h>
double calculate1( double x); // Functions defined
double calculate2( double x); // in calculate.c.
jmp_buf jmp_dest; // Destination for longjmp( )
int main( ) {
double x = 0, y1, y2;
int n = 0;
puts("--- Demonstrating non-local jumps ---\n");
switch( setjmp( jmp_dest)) // Jump to here for error handling
{
case 0: // The original setjmp( ) call
break;
case EDOM: // Arrived via longjmp( ) call with EDOM
puts("Domain error. "
"Negative numbers are not permitted.");
break;
case ERANGE: // Arrived via longjmp( ) call with ERANGE
puts("Range error. "
"The number you entered is too big.");
break;
default: // We should never arrive here.
puts("Unknown error.");
exit( EXIT_FAILURE );
}
printf("Enter a number: ");
do {
if ( (n = scanf("%lf", &x)) < 0) // Read in a number.
exit( EXIT_FAILURE ); // Read end of file.
while ( getchar( ) != '\n') // Clear the input buffer.
;
if ( n == 0 )
printf("Invalid entry. Try again: ");
}while ( n == 0 );
y1 = calculate1(x);
y2 = calculate2(x);
printf("\nResult of Calculation 1: %G\n", y1);
printf( "Result of Calculation 2: %G\n", y2);
return 0;
}
// calculate.c: Perform some calculations.
// Functions: calculate1( ), calculate2( ).
#include <math.h>
#include <setjmp.h>
#include <errno.h>
extern jmp_buf jmp_dest; // Destination for longjmp( )
double calculate1( double x)
{
if ( x < 0)
longjmp( jmp_dest, EDOM); // Domain error
else
return sqrt(x);
}
double calculate2( double x)
{
double y = exp(x);
if ( y == HUGE_VAL)
longjmp( jmp_dest, ERANGE); // Range error
else
return y;
}