I discovered that signal sets manipulation functions are defined as macros in macOS: documentation.
Then for instance, sigemptyset always results in 0 or 1, while the standard says that it can return -1 on failure.
I can fallback to the sigemptyset function by undefing it, but why is it the way it is in Mac?
Is this just one of the quarks, or sigemptyset can never fail on a Mac?
Edit: I linked the "standard" to a wrong page; it should be this. I did not change the main text as the accepted answer pointed out this mistake and wanted to make it consistent.
Providing a function as both macro and as a true function is permissible and even encouraged practice (as, e.g., a macro that expands to efficient, inline assembly). Per POSIX:
Any function declared in a header may also be implemented as a macro defined in the header, so a function should not be declared explicitly if its header is included. [...]
(POSIX.1-2017 Vol. 2 §2.1.1 Use and Implementation of Functions)
With respect to the return values of sigemptyset, the standard defines no specific errors for that function, meaning it is not required to detect any errors. The sigismember function (to which you link under the name sigemptyset) has a specified error, but it is an optional "may fail" rather than a mandatory "shall fail" error detection. OS X, as you see in its documentation, detects no errors at all.
Related
From the signal.h manpage, the prototype(s) for rt_sigprocmask are as follows:
/* Prototype for the glibc wrapper function */
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
/* Prototype for the underlying system call */
int rt_sigprocmask(int how, const kernel_sigset_t *set,
kernel_sigset_t *oldset, size_t sigsetsize);
Seeing as kernel_sigset_t is in the prototype for rt_sigprocmask, I would presume that the definition for this type would be included in signal.h. But I am getting the error that kernel_sigset_t is undeclared when I am trying to use it in my program.
I wrote a small simple program to demonstrate the error:
#include <stdio.h>
#include <signal.h>
int main()
{
printf("%d\n", sizeof(kernel_sigset_t));
return 0;
}
Which gives this message when I compile:
>gcc -o tmp tmp.c
tmp.c: In function ‘main’:
tmp.c:5:24: error: ‘kernel_sigset_t’ undeclared (first use in this function)
5 | printf("%d\n", sizeof(kernel_sigset_t));
| ^~~~~~~~~~~~~~~
tmp.c:5:24: note: each undeclared identifier is reported only once for each function it appears in
Why is this happening?
Am I including the wrong thing, or what?
EDIT: FURTHER INFORMATION
The reason I am asking this question is because I am making a program that traces two identical programs running in parallel, and compares the arguments of every system call to check that they are equal.
In order to do this, I need to check that system call arguments that are pointers point to the same data in both of the traced programs.
So, with the rt_sigprocmask system call, I want to check that the kernel_sigset_t pointers set and oldset both point to the same data. I would do this by comparing sizeof(kernel_sigset_t) length of data at the addresses pointed to by these pointers, and see if they're the same (using process_vm_readv).
However, as kernel_sigset_t, is seemingly not defined, I don't know how to do this. As the manpage says, the kernel's sigset_t and the userspace one are different sizes: how am I supposed to know what is the correct size to compare? If I just use sigset_t, will it be correct, if the kernel one is different?
As a general rule, it's not always enough to include the header file, sometimes these definitions are buried deep within #idfef hierarchies.
For example, examining the Linux doco for the sigprocmask call, you can see the required feature test macros:
_POSIX_C_SOURCE >= 1 || _XOPEN_SOURCE || _POSIX_SOURCE
meaning that one of those has to be true in order to get sigprocmask.
However, in this particular case, the manpage shows the most likely problem. In the section detailing differences between glibc (user-space) and kernel calls, we see (emphasis added):
The kernel's definition of sigset_t differs in size from that used by the C library. In this manual page, the former is referred to as kernel_sigset_t (it is nevertheless named sigset_t in the kernel sources).
In other words, it has a different name to that shown in the documented prototype and, unfortunately, the same name as the one defined in user-space.
This is likely to lead to all sorts of issues if you mix user-space and kernel methods - my advice would be to just use the user-space ones if possible, and leave the kernel ones to, well, kernel developers :-)
From a cursory investigation, the rt variant of the system call (this is not the user-space function) was added to cater for a larger signal set - once real-time signals were added, the signal bit-mask grew beyond 32 bits so the signal set had to be expanded.
The user-space function will intelligently call the correct system call under the covers, and the older system call is still there but deprecated. That function call will also silently prevent you from fiddling with the signals used by NPTL, the native POSIX threading library.
In respect to the updates to your question, in which you state you want to track system calls to ensure the arguments passed in are the same, you don't actually need to know the size of that structure.
The way rt_sigprocmask works is that the length of the structure is actually one of the arguments, sigsetsize. So that's the size you should be using for comparison.
I am trying to do a compiler using lex and yacc, but for some reason the code does not work in my VM machine in my MAC because it says that there are some functions missing from the header . Those functions are, islower() and isupper(). ECHO and yylex for some reason are also missing. I have uninstalled and installed both bison and flex for lex and yacc, but nothing fixed it.
The same code works fine in my VM machine in a Windows computer. So my code is not the problem.
Here is the error
islower and isupper are found in <ctype.h>, not in <locale.h>. It is possible that some non-standard-conformant C library implementation provides a locale.h which also includes ctype.h, but that is certainly not the case with the standard C installation on Mac OS X (or, for that matter, Linux).
It is your responsibility to write yyerror; you must also provide an accurate prototype in any file in which it is called. It will be called automatically by the yacc/bison-generated parser, but yacc/bison does not put any particular requirements on the yyerror prototype. It can return any type, or none, since the yacc/bison-generated parser never uses the return value. And it can be a varargs function if you want to write a version which does some kind of printf-style interpolation. You'll also need to declare it in any other translation union which makes use of it (as your lexer apparentely does).
yylex is not automatically declared by the yacc/bison-generated grammar either, although it is called and is expected to return an int. With a bison-generated parser, the precise arguments provided to yylex (and yyerror) depend on a variety of bison declarations; in particular, if you specify that the lexer is reentrant, bison will provide additional arguments. In the simplest case (with no bison declarations), the prototype should be
int yylex(void);
which matches the yylex generated by lex/flex (again, without any reentrancy declarations).
In traditional C, the declaration above would not be necessary, since int is the default return type for undeclared functions and the lack of arguments in the call matches the lack of arguments in the definition. However, modern C compilers (such as clang, as found on OS X, and/or gcc) will warn you about missing prototypes even if the code would work anyway. It is highly recommended that you include explicit declarations, as mentioned by the bison manual: (section 1.9, emphasis added)
The prologue may define types and variables used in the actions. You can also use preprocessor commands to define macros used there, and use #include to include header files that do any of these things. You need to declare the lexical analyzer yylex and the error printer yyerror here, along with any other global identifiers used by the actions in the grammar rules.
I don't know where you get the impression that the compiler is complaining about ECHO, unless it is the misplaced caret; the error text clearly states that the problem is with yyerror. The caret is in the wrong place because the line being shown is the source line in your lexical definition file, whereas the line the C compiler is actually complaining about is the line generated by flex, which does not include the pattern . and is therefore spaced slightly differently.
That's a weakness in clang's mechanism for using carets to show you the precise location of the error, but I think you'll agree that on the whole it is a lot more friendly to show you the original source line with its corresponding line number.
In my code, I call functions from the string.h library (specifically, strcmp()), but I forgot to add the string library. Even without including the string library, my code compiles and runs properly as if I had included the string library.
What is happening?
A header file (e.g., string.h) only includes function declarations: that is, the return type and types and number of parameters.
The functions are defined in the C library (which is linked against your code by default), so they are are available to you whether or not you #include <string.h>. However, if you fail to #include the header file, the compiler might warn you about missing function declarations, and it can also cause problems if the return type of a function is other than int (the default for functions not otherwised declared in C).
Starting with the 1999 ISO C standard, calling a function with no visible declaration is a constraint violation, requiring a diagnostic. The diagnostic may be a non-fatal warning.
Some C compilers do not enforce the newer C99 rules by default. For example, until recently gcc's default behavior was -std=gnu89, which supports the 1989/1990 C standard with GNU-specific extensions.
Under the older rules, if you call a function with no visible declaration, an implicit declaration is created assuming that the function returns int and expects the number and types of arguments you've passed it. If that assumption is incorrect, the call's behavior is undefined. It happens that strcmp() returns an int, so if the compiler accepts the call you'll probably get away with it.
You should find out how to get your compiler to at least warn you about calls to undeclared functions. Once you've confirmed that it will do so, you should add the requires #include <string.h> to your code.
Note that the #include directive only includes the header file that declares strcmp and other standard functions, not the library. The definitions of those functions (the code that implements them) is commonly included as part of the C standard library. Linking your program to the standard library is handled by the linker, not by the compiler, and it's usually done implicitly (because you asked to compile and link a C program). (The math library, depending on the implementation, might not be linked automatically, but the implementation of the string functions almost always is.)
The string library is in fact included if you include the stdio library. But the stdio does not include the string library(not directly)
By default compiler include all necessary header file and program will successfully run.
Which Compiler you are using ?
you should use C99 compiler with -strict flags and -error flags then compiler will give you error if you call a function without including header file..
Error will look like this
implicit declaration of strcmp() found
My lecturer has asked me that in class, and I was wondering why is it a macro instead of a function?
The simple explanation would be that the standard requires assert to be a macro, if we look at the draft C99 standard(as far as I can tell the sections are the same in draft C11 standard as well) section 7.2 Diagnostics paragraph 2 says:
The assert macro shall be implemented as a macro, not as an actual
function. If the macro definition is suppressed in order to access an
actual function, the behavior is undefined.
Why does it require this, the rationale given in Rationale for International Standard—Programming Languages—C is:
It can be difficult or impossible to make assert a true function, so it is restricted to macro
form.
which is not very informative, but we can see from other requirements why. Going back to section 7.2 paragraph 1 says:
[...]If NDEBUG is defined as a macro name at the point in the source file
where is included, the assert macro is defined simply as
#define assert(ignore) ((void)0)
The assert macro is redefined according to the current state of NDEBUG
each time that is included.
This is important since it allows us an easy way to turn off assertions in release mode where you may want to take the cost of potentially expensive checks.
and the second important requirement is that it is required to use the macros __FILE__, __LINE__ and __func__, which is covered in section 7.2.1.1 The assert macro which says:
[...] the assert macro writes information about the particular call
that failed [...] the latter are respectively the values of the
preprocessing macros __FILE_ _ and __LINE_ _ and of the identifier
__func_ _) on the standard error stream in an implementation-defined format.165) It then calls the abort function.
where footnote 165 says:
The message written might be of the form:
Assertion failed: expression, function abc, file xyz, line nnn.
Having it as a macro allows the macros __FILE__ etc... to be evaluated in the proper location and as Joachim points out being a macro allows it to insert the original expression in the message it generates.
The draft C++ standard requires that the contents of the cassert header are the same as the assert.h header from Standrd C library:
The contents are the same as the Standard C library header .
See also: ISO C 7.2.
Why (void)0?
Why use (void)0 as opposed to some other expression that does nothing? We can come up with a few reasons, first this is how the assert synopsis looks in section 7.2.1.1:
void assert(scalar expression);
and it says (emphasis mine):
The assert macro puts diagnostic tests into programs; it expands to a void expression.
the expression (void)0 is consistent with the need to end up with a void expression.
Assuming we did not have that requirement, other possible expressions could have undesirable effects such as allowing uses of assert in release mode that would not be allowed in debug mode for example using plain 0 would allow us to use assert in an assignment and when used correctly would likely generate an expression result unused warning. As for using a compound statement as a comment suggests, we can see from C multi-line macro: do/while(0) vs scope block that they an have undesirable effects in some cases.
It allows capturing the file (through __FILE__) and line number (through __LINE__)
It allows the assert to be substituted for a valid expression which does nothing (i.e. ((void)0)) when building in release mode
This macro is disabled if, at the moment of including , a macro with the name NDEBUG has already been defined. This allows for a coder to include as many assert calls as needed in a source code while debugging the program and then disable all of them for the production version by simply including a line like:
#define NDEBUG
at the beginning of its code, before the inclusion of <assert.h>.
Therefore, this macro is designed to capture programming errors, not user or run-time errors, since it is generally disabled after a program exits its debugging phase.
Making it as function will increase some function calls and you can not control all such asserts in release mode.
If you use function then _FILE__, __LINE__ and __func__ will give the value of that assert function's code. Not that calling line or calling function's line.
Some assertions can be expensive to call. You've just written a high performance matrix inversion routine, and you add a sanity check
assert(is_identity(matrix * inverse))
to the end. Well, your matrices are pretty big, and if assert is a function, it would take a lot of time to do the computation before passing it into assert. Time you really don't want to spend if you're not doing debugging.
Or maybe the assertion is relatively cheap, but it's contained in a very short function that will get called in an inner loop. Or other similar circumstances.
By making assert a macro instead, you can eliminate the calculation entirely when assertions are turned off.
Why is assert a macro and not a function?
Because it should compiled in DEBUG mode and should not compiled in RELEASE mode.
What will happen if I don't include the header files when running a c program? I know that I get warnings, but the programs runs perfectly.
I know that the header files contain function declarations. Therefore when I don't include them, how does the compiler figure it out? Does it check all the header files?
I know that I get warnings, but the programs runs perfectly.
That is an unfortunate legacy of pre-ANSI C: the language did not require function prototypes, so the standard C allows it to this day (usually, a warning can be produced to find functions called without a prototype).
When you call a function with no prototype, C compiler makes assumptions about the function being called:
Function's return type is assumed to be int
All parameters are assumed to be declared (i.e. no ... vararg stuff)
All parameters are assumed to be whatever you pass after default promotions, and so on.
If the function being called with no prototype fits these assumptions, your program will run correctly; otherwise, it's undefined behavior.
Before the 1989 ANSI C standard, there was no way to declare a function and indicate the types of its parameters. You just had to be very careful to make each call consistent with the called function, with no warning from the compiler if you got it wrong (like passing an int to sqrt()). In the absence of a visible declaration, any function you call was assumed to return int; this was the "implicit int" rule. A lot of standard functions do return int, so you could often get away with omitting a #include.
The 1989 ANSI C standard (which is also, essentially, the 1990 ISO C standard) introduced prototypes, but didn't make them mandatory (and they still aren't). So if you call
int c = getchar();
it would actually work, because getchar() returns an int.
The 1999 ISO C standard dropped the implicit int rule, and made it illegal (actually a constraint violation) to call a function with no visible declaration. So if you call a standard function without the required #include, a C99-conforming compiler must issue a diagnostic (which can be just a warning). Non-prototype function declarations (ones that don't specify the types of the arguments) are still legal, but they're considered obsolescent.
(The 2011 ISO C standard didn't change much in this particular area.)
But there's still plenty of code out there that was written for C90 compilers, and most modern compilers still support the older standard.
So if you call a standard function without the required #include, what will probably happen is that (a) the compiler will warn you about the missing declaration, and (b) it will assume that the function returns int and takes whatever number and type(s) of arguments you actually passed it (also accounting for type promotion, such as short to int and float to double). If the call is correct, and if you compiler is lenient, then your code will probably work -- but you'll have one more thing to worry about if it fails, perhaps for some unrelated reason.
Variadic functions like printf are another matter. Even in C89/C90, calling printf with no visible prototype had undefined behavior. A compiler can use an entirely different calling convention for variadic functions, so printf("hello") and puts("hello") might generate quite different code. But again, for compatibility with old code, most compilers use a compatible calling convention, so for example the first "hello world" program in K&R1 will probably still compile and run.
You can also write your own declarations for standard functions; the compiler doesn't care whether it sees a declaration in a standard header or in your own source file. But there's no point in doing so. Declarations have changed subtly from one version of the standard to the next, and the headers that came with your implementation should be the correct ones.
So what will actually happen if you call a standard function without the corresponding #include?
In a typical working environment, it doesn't matter, because with any luck your program won't survive code review.
In principle, any compiler that conforms to C99 or later may reject your program with a fatal error message. (gcc will behave this way with -std=c99 -pedantic-errors) In practice, most compilers will merely print a warning. The call will probably work if the function returns int (or if you ignore the result) and if you get all the argument types correct. If the call is incorrect, the compiler may not be able to print good diagnostics. If the function doesn't return int, the compiler will probably assume that it does, and you'll get garbage results, or even crash your program.
So you can study this answer of mine, follow up by reading the various versions of the C standard, find out exactly which edition of the standard your compiler conforms to, and determine the circumstances in which you can safely omit a #include header -- with the risk that you'll mess something up next time you modify your program.
Or you can pay attention to your compiler's warnings (Which you've enabled with whatever command-line options are available), read the documentation for each function you call, add the required #includes at the top of each source file, and not have to worry about any of this stuff.
First of all: just include them.
If you don't the compiler will use the default prototype for undeclared functions, which is:
int functionName(int argument);
So it will compile, and link if the functions are available. But you will have problems at runtime.
There are a lot of things you can't do if you leave out headers:
(I'm hoping to get some more from the comments since my memory is failing on this ...)
You can't use any of the macros defined in the headers. This can be significant.
The compiler can't check that you are calling functions properly since the headers define their parameters for it.
For compatibility with old program C compilers can compile code calling functions which have not been declared, assuming the parameters and return value is of type int. What can happen? See for example this question: Troubling converting string to long long in C I think it's a great illustration of the problems you can run into if you don't include necessary headers and so don't declare functions you use. What happened to the guy was he tried to use atoll without including stdlib.h where atoll is declared:
char s[30] = { "115" };
long long t = atoll(s);
printf("Value is: %lld\n", t);
Surprisingly, this printed 0, not 115, as expected! Why? Because the compiler didn't see the declaration of atoll and assumed it's return value is an int, and so picked only part of the value left on stack by the function, in other words the return value got truncated.
That's why of the reasons it is recommended to compile your code with -Wall (all warnings on).