In Linux, Do There Exist Functions Similar to _Clearfp() and _Statusfp()

In Linux, do there exist functions similar to _clearfp() and _statusfp()?

You would need a POSIX system, or a C99 compiler that supported Annex F of the C99 Standard. You can test if Annex F is supported by checking if the macro __STDC_IEC_559__ is defined. The relevant functions would be found in <fenv.h>.

int feclearexcept(int excepts); // clears exceptions (returns 0 on success)
int fetestexcept(int excepts); // returns exceptions that are set

The exceptions passed in as excepts, and returned by fetestexcept, is a bitmask that can be test against the following macros:

FE_DIVBYZERO
FE_INEXACT
FE_INVALID
FE_OVERFLOW
FE_UNDERFLOW
FE_ALL_EXCEPT

The last macro, FE_ALL_EXCEPT, is just the bitwise-or of all the macros above it.

Detecting denormal float operations on Linux for x86

As said in the question, it seems that fenv.h has a flag FE_UNDERFLOW that on some architectures at least indicate a subnormal/denormal result. My own testing indicates that this seems to be the case on my test x86 architecture, so I will go ahead and use this for now unless a better solution is provided.

Is support of Annex K in C11 required for a conforming implementation?

Annex K is optional; it says so itself.

See K.2 paragraph 2:

An implementation that defines __STDC_LIB_EXT1__ shall conform to the
specifications in this annex.

with a footnote:

Implementations that do not define __STDC_LIB_EXT1__ are not required to conform to these
specifications.

And paragraph 3 says:

Subclause K.3 should be read as if it were merged into the parallel
structure of named subclauses of clause 7.

which is why it's not necessary to mention it in the library section, clause 7 (or at least the authors of the standard didn't feel it was necessary).

An implementation that defines __STDC_LIB_EXT1__ must define it as 201112L; both N1570 and the released C11 standard got this wrong, but it was fixed in a Technical Corrigendum.

Segmentation fault when writing to a file

I bet it only happens a first time you run it. The reason why is line 11:

11 fprintf(fp, 0);

You are basically passing fprintf a null pointer. What you probably meant to do was this:

11 fprintf(fp, "0");

Here is how I figured it out. I compiled it with debug info and ran it using debugger... lldb, to be precise:

(lldb) bt
* thread #1: tid = 0xacaaf, 0x00007fff90f4dcf6 libsystem_c.dylib__vfprintf + 327, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
* frame #0: 0x00007fff90f4dcf6 libsystem_c.dylib
__vfprintf + 327

frame #1: 0x00007fff90f762e7 libsystem_c.dylib`__v2printf + 471

frame #2: 0x00007fff90f766bc libsystem_c.dylib`__xvprintf + 633

frame #3: 0x00007fff90f4db36 libsystem_c.dylib`vfprintf_l + 54

frame #4: 0x00007fff90f4669b libsystem_c.dylib`fprintf + 186

frame #5: 0x0000000100000e9d test.out`main(argc=1,

argv=0x00007fff5fbffc60) + 109 at test.c:11
frame #6: 0x00007fff8f9c95fd libdyld.dylib`start + 1

...if you look at frame 5, you will see the offending line of code.



Related Topics



Leave a reply



Submit