How to make use of madvise and associated macros? - c

When I compile using gcc --std=c99 -g -Wall ... I get this:
warning: implicit declaration of function ‘madvise’ [-Wimplicit-function-declaration]
...
error: ‘MADV_DONTNEED’ undeclared
...
So I used this: `gcc -print-prog-name=cpp` -v to find where my compiler is looking for headers and found that there is only header for sys/mman.h so I looked at the files source and it shows this:
#ifdef __USE_BSD
/* Advise the system about particular usage patterns the program follows
for the region starting at ADDR and extending LEN bytes. */
extern int madvise (void *__addr, size_t __len, int __advice) __THROW;
#endif
I did some research into why __USE_BSD wouldn't be defined but didn't find much. What I did find is that features.h can be used to define it. So I tried putting this at the top of my code:
#define _BSD_SOURCE 1
#include <features.h>
This seems to work but I've never done this sort of thing before. am I going about this the right way? I'm just concerned that my methodology is a bit hacky...

I happened across a reference to feature_test_macros(7) which suggests defining as I have in my question, or (as I have opted to do) use the -D flag to define the macros using the compiler. I chose this option so that the macros I need defined will be defined for across multiple source files.

Related

GNUC for ARM. Why would a #define need a defined type?

I'm trying to build the WolfSSL, using GNU-C 7.3.1 for ARMv7.
I am getting an error where I've never seen one before. In this code fragment for Wolfio.h:
#ifndef WOLFSSL_NO_SOCK
#ifndef XSOCKLENT
#ifdef USE_WINDOWS_API
#define XSOCKLENT int
#else
#define XSOCKLENT socklen_t
#endif
#endif
/* Socket Addr Support */
#ifdef HAVE_SOCKADDR
#ifndef HAVE_SOCKADDR_DEFINED
The 6th line in the above fragment:
#define XSOCKLENT socklen_t
Gives the error:
wolfio.h:383:31: error: unknown type name 'socklen_t'; did you mean '__socklen_t'?
Huh...?? why would a #define assignment need a type that exists?
I tried an alternate test in a dummy file of a different project, with the following. Neither of which are defined:
#define MYTYPE SOMETHING
And I received no error.
Because for decades I've believed that #defines are just preprocessor replacements. And doesn't analyze any of the source. My test in the dummy file confirms that belief.
So, somehow inside this large project, the GNU compiler got into it's head that a #define is really just a typedef?? And the RHS of the #define is required to be a defined type?
Is there a compiler or #pragma setting that makes it think this?
The project is for a TI ARM device, using their Code Composer studio
For reference, the compile args are (without my includes):
-mcpu=cortex-a8
-march=armv7-a
-mtune=cortex-a8
-marm
-mfloat-abi=hard
-mfpu=neon
-Dam3359
-Dam335x
-Dxdc_target_types__=gnu/targets/std.h
-Dxdc_target_name__=gnu/targets/arm/A8F
{includes}
-Ofast
-Wall
-specs="nosys.specs"
Any advice is appreciated.
#define does not care about any types as preprocessor only textually replaces strings (more precise tokens) and does not know anything about the C language and types.
The error is generated by the C compiler when the C file after the preprocessing was compiled (ie all XSOCKLENT tokens were replace by the socklen_t token).
I think this is just a misunderstanding caused by the compiler's error message format.
You are quite right that there is nothing wrong per se with defining a macro that expands to a nonexistent type. The issue is almost certainly that some other part of your program includes this header and declares a XSOCKLENT my_var; without having included <sys/socket.h> to get the socklen_t type defined. That would account for the unknown type name error.
What's confusing you is that the line number referenced by the error message is the definition of the XSOCKLENT macro. This is a feature; the idea being that when code resulting from macro expansion causes an error, then more often than not, the bug is in the way the macro was defined. Here, that happens to not be the case. But if you look at the next bit of the compiler output, you ought to see the file and line where the macro was used. That should be the file that needs to be including <sys/socket.h>. (Or maybe you want Wolfio.h to include it; you'll have to see what makes the most sense.)
Example: with the file
#define FOO djewiodjwoidjeiwojdiwe
FOO x;
GCC 11 outputs:
foo.c:1:13: error: unknown type name ‘djewiodjwoidjeiwojdiwe’
1 | #define FOO djewiodjwoidjeiwojdiwe
| ^~~~~~~~~~~~~~~~~~~~~~
foo.c:3:1: note: in expansion of macro ‘FOO’
3 | FOO x;
| ^~~
Note the first message points to line 1, where the macro is defined, and the second part of the message points to line 3, where it is used. If one isn't what you are looking for, then try the other.

Adding a code to be compiled in lex first

I'm looking for a way to insert an #undef to the lex generated source code that will appear before the built in lines lex generates.
When compiling a file.l with lex, I generate a lex.yy.c file. In my file.l I have written :
#include "y.tab.h"
#undef __STRICT_ANSI__
#include <string.h>
The #undef helps me compile the code under the flag -std=c99 So it needs to be done before including string.h. But the generated file includes string.h before copying my undef.
Without the #undef I am getting a lot of warnings due to the use of strdup. I have seen the normal fixes using flags, but like I said I can't access the makefile.
Adding 'manually' the line
#undef __STRICT_ANSI__
into lex.yy.c before fixes everything. But i prefer not to touch any of the generated code and have it done by lex.
I have read this,
strdup(): Confused about warnings ('implicit declaration', 'makes pointer...without a cast', memory leak)
And like i said it does solve it.
But only if I can somehow force the generated file to run the undef first.
To start with, #undef __STRICT_ASCII__ is not the correct way to enable the declaration of Posix functions like strdup.
Posix extensions which are declared in standard C library header files are made conditional on "feature test macros". You can read a summary in man feature_test_macros but in any case, the documentation for any function which requires a feature test macro includes a description of which macros are required. In the case of strdup, we can read in man strdup:
Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
strdup():
_XOPEN_SOURCE >= 500
(Followed by more possibilities.)
Personally, I always use
#define _XOPEN_SOURCE 700
which requests declarations for all functions in the latest version of Posix.
One way to insert the feature test macro before any include of a standard library function is to do so on the compile command line:
-D_XOPEN_SOURCE=700
I like doing it this way, because I can add it to my Makefile and then it applies to every compilation (which is basically what I want). Usually, makefiles include a feature which allows you to add this option to your compiler flags without modifying the file. For example, the following will often work:
make file CPPFLAGS="-D_XOPEN_SOURCE=700"
(CPPFLAGS is a common makefile variable used to set preprocessor flags.)
But if you want to put it into your flex file, you can use a %top block:
%top {
#define _XOPEN_SOURCE 700
}
%top is like %{ but it puts the inserted code right at the beginning of the generated code.
If nothing else works, you can always just insert the declaration for strdup, (also taken from man strdup) into your flex prologue.
%{
char *strdup(const char *s);
#include "y.tab.h"
%}
Both the C standard and the Posix standard allow explicit declaration of library functions (but not macros) as an alternative to including relevant headers.

Use open_memstream with c99

I am trying to use the open_memstream function in my C code. However I cannot seem to compile it. Minimal working example as follows:
#include <stdio.h>
int main(void) {
char *buf;
size_t sz;
FILE *stream = open_memstream(&buf, &sz);
putc('A', stream);
fclose(stream);
}
And I also use the following command to compile it:
gcc -std=c99 -o test test.c
After some research, I found that I need to define a macro before I include stdio.h. However the following example code was to no avail.
#define __USE_POSIX
#define __USE_XOPEN
#include <stdio.h>
The following compiler warnings are thrown; I assume the second warning is because of the first one.
test.c:7:17: warning: implicit declaration of function ‘open_memstream’ [-Wimplicit-function-declaration]
FILE *stream = open_memstream(&buf, &sz);
^
test.c:7:17: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
The __USE_* macros are internal to glibc's headers, and defining them yourself does not work. You should instead do one of the following:
Compile your program with -std=gnu11 instead of -std=c99 and don't define any special macros. This is the easiest change. Conveniently, -std=gnu11 is the default with newer versions of GCC.
If you have some concrete reason to want to select an old, strict conformance mode, but also you want POSIX extensions to C, then you can use the documented POSIX feature selection macros:
#define _XOPEN_SOURCE 700
or
#define _POSIX_C_SOURCE 200809L
These must be defined before including any standard headers. The difference is that _XOPEN_SOURCE requests an additional set of features (the "XSI" functions). See the Feature Test macros section of the glibc manual for more detail.
Note that if you need to request strict conformance mode from the library, using a -std=cXX option, then you almost certainly also want to use the -Wall and -Wpedantic options to enable strict conformance checking for the language. (You should use at least -Wall even if you don't need strict conformance checking.)

How to find irrelevant unused attributes?

While reading parts of the code of a big C project, I found some arguments that were marked as unused but were in fact used in the function.
I thought about grepping the unused attributes but there are too many of them to manually verify if they are really unused.
My question is the following: is there a way to ask to gcc (or clang) if any attributes are not justified or not applied? Basically, for that kind of code:
int f(int arg __attribute__((unused))) {
return arg + 2;
}
I would like a warning telling my that my argument is not unused.
I can't really take credit for this, as I stumbled upon it at http://sourcefrog.net/weblog/software/languages/C/unused.html.
It causes UNUSED variables to give compiler errors when you attempt to use them.
#ifdef UNUSED
// Do notthing if UNUSED is defined
#elif defined(__GNUC__)
// Using the gcc compiler - do the magic!
#define UNUSED(x) UNUSED_ ## x __attribute__((unused))
#elif defined(__LCLINT__)
#define UNUSED(x) /*#unused#*/ x
#else
// unknown compiler - just remove the macro
#define UNUSED(x) x
#endif
It wont help you find unused variables, but once found you can ensure they really are unused.
You can #define the unused away, like so
#define unused
Empty __attribute__ statements are ignore and the compiler shall issues a warning about "unused parameter, if ran with the right option (-Wunused-parameter) enabling warnings.
However this could break the code if the character sequence unused is used somewhere else in the code, as it would disappear there also.
I cannot speak for GCC, but you can teach Clang to scream and shout using the -Werror-used-but-marked-unused flag.
You can cover the opposite case too using -W(error-)unused-parameter.
Because there are so many useful warnings in Clang, I usually just use -Werror -Weverything, though—selectively ignoring the ones I’m not interested in, and preventing e.g. implementing/calling deprecated functions/methods to be promoted to errors using -Wno-error-....
I used alk answer but I'm giving more details for those facing the same problem.
First part:
alk suggested to define a macro named unused. Since it's a large project with several build units and Makefiles, I decided to define the macro using gcc:
gcc -Dunused= ...
Then, I've cleaned-up the project and rebuilt:
make clean && make
That went very badly because of variables called unused_something in the code. So I had to rename these variables in order to continue.
Since I'm using the -Wall option, I'm now getting a lot of warnings that all look like:
char/serial.c: In function ‘serial_write’:
char/serial.c:151:69: warning: unused parameter ‘odf’ [-Wunused-parameter]
static size_t serial_write(tty_struct_t *tty, open_file_descriptor* odf __attribute__((unused)), const unsigned char* buf, size_t count)
^
So I reran with:
make clean && make > out 2>&1
And now, I grep the result:
grep Wunused-parameter out
I'm getting all the warnings with the name of the file and the line number.
Second part:
Since I use git, I can directly do:
git grep -n "((unused))"
With that, I have all the lines containing the attribute unused. However, if a line contains two or more unused attribute, I'll get it only once.
Last part:
I check which lines are not on both outputs, manually :/.

How do you include a header file that may or may not exist?

Let's assume I define BAR in foo.h. But foo.h might not exist. How do I include it, without the compiler complaining at me?
#include "foo.h"
#ifndef BAR
#define BAR 1
#endif
int main()
{
return BAR;
}
Therefore, if BAR was defined as 2 in foo.h, then the program would return 2 if foo.h exists and 1 if foo.h does not exist.
In general, you'll need to do something external to do this - e.g. by doing something like playing around with the search path (as suggested in the comments) and providing an empty foo.h as a fallback, or wrapping the #include inside a #ifdef HAS_FOO_H...#endif and setting HAS_FOO_H by a compiler switch (-DHAS_FOO_H for gcc/clang etc.).
If you know that you are using a particular compiler, and portability is not an issue, note that some compilers do support including a file which may or may not exist, as an extension. For example, see clang's __has_include feature.
Use a tool like GNU Autoconf, that's what it's designed for. (On windows, you may prefer to use CMake).
So in your configure.ac, you'd have a line like:
AC_CHECK_HEADERS([foo.h])
Which, after running configure, would define HAVE_FOO_H, which you can test like this:
#ifdef HAVE_FOO_H
#include "foo.h"
#else
#define BAR 1
#endif
If you intend to go down the autotools route (that is autoconf and automake, because they work well together), I suggest you start with this excellent tutorial.

Resources