I just noticed this line in the getrusage man page:
Including <sys/time.h> is not required these days, but increases portability. (Indeed, struct timeval is defined in <sys/time.h>)
What? Since struct rusage contains struct timeval as a member, surely sys/resource.h must include sys/time.h or the type would be incomplete and unusable?
How could this comment ever have made sense? How could it ever have not been necessary? How could portability have ever been helped?
In general, it was not uncommon in the early days of C for you to have to manually include header file A before header file B. Maybe an early version of the preprocessor couldn't do nested includes, or maybe it was just stylistic (manpages would often directly include the header files for relevant structures).
"These days", sys/resource.h must either include sys/time.h or repeat the definition of struct timeval, but not every system follows the standard completely.
It's because the BSD's require it:
FreeBSD and OpenBSD need sys/time.h, not just time.h, before
sys/resource.h.
See this page on UNIX Portability for details.
Related
The socket.h BSP header that has the '__P' as
int bind __P((int, const struct sockaddr *, socklen_t))
Could you tell me what is the meaning of '__P' here? Thank you so much!
This is a portability hack. K&R C (the version before C was standardized by ANSI and ISO) didn't declare functions with types and named arguments in the parentheses. As a consequence, this declaration needs to be this on K&R C:
int bind();
and this on standard C:
int bind(int, const struct sockaddr *, socklen_t);
The __P macro is designed to paper over these differences and allow the compiler to generate the appropriate prototype depending on the existence of the __STDC__ macro which specifies standard C.
Note that C was standardized by ANSI in 1989 and by ISO in 1990, and has gone through several revisions since then, most notably in 1999 and 2011. It is highly unlikely that anyone is still using a K&R C compiler on a modern system because for many architectures, their support in the operating system in question appeared only in compilers which supported standard C. Also, most people are using systems which have been upgraded or built in the past 30 years.
However, some very old software may be written in K&R C, and as such, this technique allows such code to work. The lifetime of such code is necessarily limited, though, as the latest versions of GCC and clang don't support K&R C anymore, so finding an old compiler may be tricky.
I had written plenty of code using Booleans and complied and built with no problem. Then the compiler and even the editor no longer recognizes "bool". A fix I did was to "#include <stdbool.h>" to recognize the Booleans.
But I'd like to know what could possibly cause this problem?
In C11, the type bool is only defined if the standard header stdbool.h is included. Otherwise, the type has to be referred to as _Bool. This was the result of the complete absence of a boolean type in earlier revisions of the standard, and the focus on backwards compatibility in the evolution of said standard.
In C++, the bool type is available without including any header, just like int.
Your question is about GCC, not about the C standard, but while GCC does take some obscure liberties with the C standard if you do not use commandline options such as -std=c11 -pedantic to make it a standard-compliant compiler, in the case of the type bool, it follows the C standard and abstains from defining it.
It is likely that you were compiling code as C++ previously and are now compiling it as C. Another possibility is that you were including an application header that was including stdbool.h or that provided its own definition of bool, and that you ceased to include this header.
(It would even be possible to imagine in theory that the header in question was a system header that was including stdbool.h previously and ceased to when you upgraded your compilation platform. In principle, there is no guarantee about which system header may include what other system headers. In practice, though, since the only purpose of stdbool.h is to preserve compatibility with old code that does not include it, stdbool.h would never be included by another system header.)
I'm using MSVC to compile some C code which uses standard-library functions, such as getenv(), sprintf and others, with /W3 set for warnings. I'm told by MSVC that:
'getenv': This function or variable may be unsafe. Consider using _dupenv_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS
Questions:
Why would this be unsafe, theoretically - as opposed to its use on other platforms?
Is it unsafe on Windows in practice?
Assuming I'm not writing security-oriented code - should I disable this warning or actually start aliasing a bunch of standard library functions?
getenv() is potentially unsafe in that subsequent calls to that same function may invalidate earlier returned pointers. As a result, usage such as
char *a = getenv("A");
char *b = getenv("B");
/* do stuff with both a and b */
may break, because there's no guarantee a is still usable at that point.
getenv_s() - available in the C standard library since C11 - avoids this by immediately copying the value into a caller-supplied buffer, where the caller has full control over the buffer's lifetime. dupenv_s() avoids this by making the caller responsible for managing the lifetime of the allocated buffer.
However, the signature for getenv_s is somewhat controvertial, and the function may even be removed from the C standard at some point... see this report.
getenv suffers like much of the classic C Standard Library by not bounding the string buffer length. This is where security bugs like buffer overrun often originate from.
If you look at getenv_s you'll see it provides an explicit bound on the length of the returned string. It's recommended for all coding by the Security Development Lifecycle best practice, which is why Visual C++ emits deprecation warnings for the less secure versions.
See MSDN and this blog post
There was an effort by Microsoft to get the C/C++ ISO Standard Library to include the Secure CRT here, some of which was approved for C11 Annex K as noted here. That also means that getenv_s should be part of the C++17 Standard Library by reference. That said, Annex K is officially considered optional for conformance. The _s bounds-checking versions of these functions are also still a subject of some debate in the C/C++ community.
When I have searched for the header unistd.h, in The Open Group, I found that it contains the standard symbolic constants & types and for sys/types.h it said for data types.
Then I found that both have uid_t, pid_t and several similar types.
I am confused why they have divided so and what are the differences between them. I have googled but I didn't get a satisfactory answers.
I will be thankful if some one can give me detailed explanation.
Thank you.
The division of the POSIX and C header in fine grained files probably comes from the old days when compilation might take a long time, and adding unnecesary header files made the time longer.
If you only need the OS types, say for the prototypes of your functions, then just #include <sys/types.h>. However if you need the function definitions, then you #include <unistd.h> or any of the other system headers, as needed.
Naturally there are types that are in both headers, as you cannot declare some functions without their necessary types.
But these different declarations of the same type are guaranteed to be the same, so there is no problem if you include both.
I recently happened to come across the preprocessing option most Fortran compilers support these days (as explained e.g. in the Fortran Wiki) . Coming from a C background, I would like to better understand the mechanics and caveats related to the (Fortran-)preprocessor's #include directive.
To avoid any confusion right from the beginning: there are two include directives in Fortran (see e.g. F77 reference)
include "foo" is a compiler directive, i.e. foo can only contain Fortran statements
#include "bar" is a preprocessor directive, i.e. bar can contain #defines and the like
I am aware of this difference and I am interested in the second case only (my question is therefore not a duplicate of this post).
I'll explain my questions using an example: assume we have two files, a header file (macro.h) and a source file (display.F):
macro.h
#define MSG() say_hello()
display.F
#include "macro.h"
PROGRAM display
CALL MSG()
CALL another_message()
END
SUBROUTINE say_hello()
WRITE(*,*) 'Hello.'
END
SUBROUTINE another_message()
CALL MSG()
END
Here are my questions:
Scope
where (globally, locally in the SUBROUTINE etc.) is the macro MSG() defined if I include macro.h:
at the beginning of the file (as above)?
at the beginning of the PROGRAM display (and nowhere else)?
at the beginning of e.g. SUBROUTINE another_message() (and nowhere else)?
From testing it seems: 1. globally, 2. in PROGRAM and all SUBROUTINES, 3. in that SUBROUTINE only. A confirmation of these assumptions and some theoretical explanations why would be great.
What of above (1. - 3.) is best practice for preprocessor includes?
Include Guards
If I have a multi-file project and I include header.h in multiple *.F source files, do I need to provide include guards?
In case the answers to the above questions should be compiler dependent (as preprocessing is not Fortran standard), I'd be most interested in ifort's behaviour.
The rules are the same as for the C preprocessor you know. GCC even uses the same cpp for C and Fortran (for Fortran in the traditional mode). Therefore there is no scope around, everything is just a text and the preprocessor doesn't care about program units.
Therefore, 1., 2. and 3. all are valid from the place of their definition until the file end or until #undef. They are also valid in recursively #included files.
If by guards you mean #undef then yes, otherwise a warning or error about redefinition appears, but only if you include all those files from a single file. If they are independent then no.
The key is to think about the preprocessor as a text replacement tool. It knows nothing about Fortran.
Last thing, the preprocessor is non-standard, but widely available.