user1777862
user1777862

Reputation: 61

Difference(s) between flushall() and _flushall()

The compiler (Visual C++) always corrects me when I type flushall();

warning C4996: 'flushall': The POSIX name for this item is deprecated. Instead, use the ISO C++ conformant name: _flushall.

They both work for me, is there any difference?

Upvotes: 2

Views: 10493

Answers (2)

Hans Passant
Hans Passant

Reputation: 942237

This goes back to late 1988, back when Dave Cutler's team started development on Windows NT. The design goal was to create an operating system with three distinct api layers, Winapi, OS/2 and POSIX. POSIX was very new back then, the very first version was released in 1988 as well. It got included because it was listed as a requirement in a USA government standard, FIPS 151-2.

Back then the Unix Wars started to get serious. Pretty vicious with intentional differences in competing implementations. Main combatants were the Open Software Foundation, an industry group that feared Sun's increasing dominance and Unix International, a group around AT&T. That dust didn't settle until 1993 and the formation of the COSE alliance, now Open Group.

This makes the exact origin of flushall() pretty hard to trace, it was very much the wild wild west back then. Microsoft was also in the C compiler business so of course they released the tools to build programs that ran on the POSIX layer, including headers that declared the functions. So surely the time that flushall came about in their toolset. I don't have a copy anymore to check, destroyed by a leaky roof.

The NT Posix and OS/2 api layers never gained much traction, significantly overshadowed by Win32's runaway success. They were entirely dropped in 2001 with the XP release. Which, I think, was also around the time that they started deprecating the original Posix function names. Clearly it didn't make much sense anymore to keep these declarations around when they were no longer supported by the operating system. The Posix names are fairly awkward, short lower-case names in the global namespace cause many accidents.

They were however never completely removed, still documented to this day. Which is why you got the warning. Rather then choosing, do favor standard C library names, fflush().

Upvotes: 2

R.. GitHub STOP HELPING ICE
R.. GitHub STOP HELPING ICE

Reputation: 215517

This warning is nonsensical; flushall is not POSIX, and to my knowledge, never was. The correct ISO C way to flush all open stdio streams is fflush(NULL);.

To shed some more light on the issue, I believe this is a generic warning message Visual C uses for functions which are not part of the C standard, but which their standard library has for some minimal degree of compatibility. Most of these functions are things like open and read, and correspond in some vague way to the POSIX functions by the same name, and can be thought of as the lower-level primitives underlying stdio, etc. Some, like flushall, are not actually from POSIX, but just based on oddball functions copied from various legacy unices.

Since these functions are not actually part of the C (or C++) standards, and the C standard (and possibly also the C++ standard...?) reserves for the application identifiers which are not explicitly defined or reserved in the standard, it's non-conformant to expose in the standard headers names like open or flushall. POSIX gets around this by using feature test macros by which an application can make the namespace guarantees it wants from the implementation explict, but Microsoft instead took an approach of deprecating the POSIX-like names and offering an alternative set of functions, prefixed with underscores, which makes them part of the namespace reserved for the implementation. The warning is recommending that you use these Microsoft-specific names, so that your code would still compile if you turned on the options (probably controlled by macros of compiler switches) for a strict namespace conformance in the headers.

Unfortunately, writing code the Microsoft-recommended way with the underscore-prefixed names renders your code completely non-portable. Since these names are in the namespace reserved for the implementation, other platforms might happen to use the same names for functions which do completely different things, and being as they're reserved, you would not be allowed to replace or #define around them to remap them to other functions.

In short: I would find the warning flag that's generating this warning, and turn it off. Along with the one that spews FUD that such-and-such standard function is "insecure" and you should use the _s-suffixed function instead. But if the only function you need is fflushall(), simply replace it with fflush(NULL); and you're good to go.

Upvotes: 9

Related Questions