After importing unistd.h, compiler states that sbrk() is an implicit declaration. Why is this? - c

I'm trying to implement malloc on CentOS, but I keep getting the error:
malloc.c: In function ‘malloc’:
malloc.c:11:5: error: implicit declaration of function ‘sbrk’ [-Werror=implicit-function-declaration]
mem_ptr = sbrk(SIXTY_FOUR_K); /* Allocate 64 kB of memory */
Here is the code that the compiler warning is referencing:
#include "malloc.h"
#include <unistd.h>
void * malloc(size_t bytes) {
uintptr_t mem_ptr;
if (bytes <= 0) { /* If user passes in bad value, return NULL */
return NULL;
}
mem_ptr = sbrk(SIXTY_FOUR_K); /* Allocate 64 kB of memory */
if (mem_ptr == -1) { /* sbrk() failed */
return NULL;
}
return (void *)mem_ptr;
}
According to the documentation on sbrk, you should just have to import unistd.h, which I do. Is there something I'm doing wrong?

Did you take a look at the Feature Test Macro requirements?
Feature Test Macro Requirements for glibc (see
feature_test_macros(7)):
brk(), sbrk():
Since glibc 2.12:
_BSD_SOURCE || _SVID_SOURCE ||
(_XOPEN_SOURCE >= 500 ||
_XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED) &&
!(_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600)
Before glibc 2.12:
_BSD_SOURCE || _SVID_SOURCE || _XOPEN_SOURCE >= 500 || _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED
See if compiling with something like -D_SVID_SOURCE will work (though it looks like there are a number of options based on that macro list)
As of glibc 2.19, a new feature test macro was added, _DEFAULT_SOURCE which is meant to replace _BSD_SOURCE and _SVID_SOURCE. For more information on _DEFAULT_SOURCE, see this question: What does -D_DEFAULT_SOURCE do?

Related

Check if `_GNU_SOURCE` or `_BSD_SOURCE` is supported by the libc?

I am curious if asprintf is available. Some libc implementations provide it under specific Feature Test Macros. Namely if you #define _GNU_SOURCE or #define _BSD_SOURCE you can get asprintf and a few other nice nonstandard extensions when you #include <stdio.h>.
There are a decent number of libc implementation. glibc obviously has asprintf; but so do a number of others.
How do I test if the libc implementation supports _BSD_SOURCE or _GNU_SOURCE?
My current test is bad, as it's just a kernel check not a compiler + libc + version check:
#if defined(__linux) || defined(__linux__) || defined(linux)
#define _GNU_SOURCE
#elif defined(BSD) || defined(__FreeBSD__) || defined(__FreeBSD__) || \
defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || \
defined(__DragonFly__)
#define _BSD_SOURCE
#endif
#include <stdio.h>
PS: I'm also using CMake and considered a check_symbol_exists(asprintf "stdio.h" HAVE_ASPRINTF) but not sure that'd suffice.

warning: implicit declaration of function 'daemon'

I get this warning while compiling my program. daemon() is declared in unistd.h and its included. How to fix this or make it disappear?
error:
dcron.c: In function 'main':
dcron.c:35:4: warning: implicit declaration of function 'daemon' [-Wimplicit-function-declaration]
if (daemon(1, 0) != 0) {
^
part of program:
if (daemon(1, 0) != 0) {
fprintf(stderr, "error: failed to daemonize\n");
syslog(LOG_NOTICE, "error: failed to daemonize");
return 1;
}
setup:
gcc4.8.2, glibc2.19
CFLAGS=-std=c99 -Wall -Wpedantic -Wextra
You need to add the relevant header file and enable the _BSD_SOURCE feature test macro:
#define _BSD_SOURCE
#include <unistd.h>
From man 3 daemon:
Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
daemon(): _BSD_SOURCE || (_XOPEN_SOURCE && _XOPEN_SOURCE < 500)
On Linux daemon() is made available by #defineing either
_XOPEN_SOURCE
_BSD_SOURCE
by doing
#define _XOPEN_SOURCE
or
#define _BSD_SOURCE
before #includeing
#include <unistd.h>
or by adding -D _XOPEN_SOURCE or -D _BSD_SOURCE to the compilation command.

implicit declaration using -std=c99

I'm getting this warning: (-std=c99 -pedantic)
warning: implicit declaration of function ‘strndup’ [-Wimplicit-function-declaration]
but I'm importing these libs:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
So what?! :(
// file.c:
#include "file.h"
strndup(...)
// file.h:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
The issue is your usage of the -std=c99 option. Since strndup() isn't part of C99, and you're asking the compiler to go into standards compliant mode, it won't provide the prototype for it. It still links of course, because your C library has it.
While you may be able to coax gcc into providing it by specifying feature macros yourself, I'd say it doesn't make much sense to be in C99 compliance mode and ask for GNU extensions for example. gcc already provides a mode for this, which will solve your warning: -std=gnu99.
My man strndup says
Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
strdup():
_SVID_SOURCE || _BSD_SOURCE || _XOPEN_SOURCE >= 500 ||
_XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED
|| /* Since glibc 2.12: */ _POSIX_C_SOURCE >= 200809L
strndup():
Since glibc 2.10:
_POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700
Before glibc 2.10:
_GNU_SOURCE
strdupa(), strndupa(): _GNU_SOURCE
So I'd need to, eg, #define _POSIX_C_SOURCE 200809L before the first #include in your file.
see man 7 feature_test_macros
strndup is a GNU extension, so you need to compile with -D_GNU_SOURCE on the command line, or stick a #define _GNU_SOURCE 1 in your source files before the #include lines
This happened to me, and I added #define _XOPEN_SOURCE 500 and the warning went away.

Constants not loaded by compiler

I started studying POSIX timers, so I started also doing some exercises, but I immediately had some problems with the compiler.
When compiling this code, I get some strange messages about macros like CLOCK_MONOTONIC. Those are defined in various libraries like time.h etc. but the compiler gives me errors as if they are not defined.
It is strange because I am using a Fedora 16, and some of my friends with Ubuntu get less compiler errors than I :-O
I am compiling with gcc -O0 -g3 -Wall -c -fmessage-length=0 -std=c99 -lrt
Here the errors I get:
struct sigevent sigeventStruct gives:
storage size of ‘sigeventStruct’ isn’t known
unused variable ‘sigeventStruct’ [-Wunused-variable]
Type 'sigevent' could not be resolved
unknown type name ‘sigevent’
sigeventStruct.sigev_notify = SIGEV_SIGNAL gives:
‘SIGEV_SIGNAL’ undeclared (first use in this function)
request for member ‘sigev_notify’ in something not a structure or union
Field 'sigev_notify' could not be resolved
if(timer_create(CLOCK_MONOTONIC, sigeventStruct, numero1) == -1) gives:
implicit declaration of function ‘timer_create’ [-Wimplicit-function- declaration]
‘CLOCK_MONOTONIC’ undeclared (first use in this function)
Symbol 'CLOCK_MONOTONIC' could not be resolved
Here is the code:
#include <stdio.h>
#include <fcntl.h>
#include <time.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
int main()
{
timer_t numero1;
struct sigevent sigeventStruct;
sigeventStruct.sigev_notify = SIGEV_SIGNAL;
if(timer_create(CLOCK_MONOTONIC, sigeventStruct, numero1) == -1)
{
printf( "Errore: %s\n", strerror( errno ) );
}
return 0;
}
Firstly, you can compile your code with -std=gnu99 instead of -std=c99 if you want to have the identifiers SIGEV_SIGNAL, sigeventStruct, and CLOCK_MONOTONIC available.
As noted by #adwoodland these identifiers are declared when _POSIX_C_SOURCE is set to a value >= 199309L, which is the case with -std=gnu99. You can also use -D_POSIX_C_SOURCE=199309L -std=c99 or have the macro defined in source code.
Secondly, see the timer_create prototype, you have to pass pointers as the second and the third argument to the function:
timer_create(CLOCK_MONOTONIC, &sigeventStruct, &numero1)
^ ^
Also you have to include the standard header string.h for strerror function declaration.
If you are using -std=c99 you need to tell gcc you're still using recent versions of POSIX:
#define _POSIX_C_SOURCE 199309L
before any #include, or even with -D on the command line.
Other errors:
Missing #include <string.h>
You need a pointer for timer_create, i.e. &sigeventStruct instead of just sigeventStruct
The other answers suggest _POSIX_C_SOURCE as the enabling macro. That certainly works, but it doesn't necessarily enable everything that is in the Single Unix Specification (SUS). For that, you should set _XOPEN_SOURCE, which also automatically sets _POSIX_C_SOURCE. I have a header I call "posixver.h" which contains:
/*
** Include this file before including system headers. By default, with
** C99 support from the compiler, it requests POSIX 2001 support. With
** C89 support only, it requests POSIX 1997 support. Override the
** default behaviour by setting either _XOPEN_SOURCE or _POSIX_C_SOURCE.
*/
/* _XOPEN_SOURCE 700 is loosely equivalent to _POSIX_C_SOURCE 200809L */
/* _XOPEN_SOURCE 600 is loosely equivalent to _POSIX_C_SOURCE 200112L */
/* _XOPEN_SOURCE 500 is loosely equivalent to _POSIX_C_SOURCE 199506L */
#if !defined(_XOPEN_SOURCE) && !defined(_POSIX_C_SOURCE)
#if __STDC_VERSION__ >= 199901L
#define _XOPEN_SOURCE 600 /* SUS v3, POSIX 1003.1 2004 (POSIX 2001 + Corrigenda) */
#else
#define _XOPEN_SOURCE 500 /* SUS v2, POSIX 1003.1 1997 */
#endif /* __STDC_VERSION__ */
#endif /* !_XOPEN_SOURCE && !_POSIX_C_SOURCE */
It is tuned for the systems I work with which don't all recognize the 700 value. If you are working on a relatively modern Linux, I believe you can use 700. It's in a header so that I only have to change one file when I want to alter the rules.
Referring to the CLOCK_MONOTONIC not being defined problem:
As Caterpillar pointed out this is an eclipse bug, more precisely a CDT-Indexer bug with a workaround at eclipse bugs, comment 12
I solved a lot of problems with -std=gnu99 (without specifing any POSIX versions) but I am still having
CLOCK_MONOTONIC could not be resolved
Searching on internet I found some Eclipse bugreports with people complaining about this. Have to check better if is an Eclipse bug, because with
gcc -Wall -w -o Blala timer.c -std=gnu99 -lrt
it compiles

Sensible line buffer size in C?

I'm using popen to read output from shell commands. I will use fgets to read line by line.
My question is how to choose the best buffer size for my char* buffer? I remember from a professor telling us to include <limits.h> and use LINE_MAX for such things. It works fine on my Mac, but there's no LINE_MAX on Linux.
This mailing list archive poses the same question, but no answer to my question
http://bytes.com/topic/c/answers/843278-not-able-locate-line_max-limits-h
When <limits.h> does not define LINE_MAX, look at _POSIX2_LINE_MAX, which is required to be at least 2048. I usually use 4096.
Also look for the (new) POSIX functions getline() and getdelim() - both at the same URL. These allocate memory as necessary.
Program (posix2_line_max.c)
#include "posixver.h"
#include <limits.h>
#include <stdio.h>
int main(void)
{
printf("%d\n", _POSIX2_LINE_MAX);
return 0;
}
Output:
2048
posixver.h
#ifndef JLSS_ID_POSIXVER_H
#define JLSS_ID_POSIXVER_H
/*
** Include this file before including system headers. By default, with
** C99 support from the compiler, it requests POSIX 2001 support. With
** C89 support only, it requests POSIX 1997 support. Override the
** default behaviour by setting either _XOPEN_SOURCE or _POSIX_C_SOURCE.
*/
/* _XOPEN_SOURCE 700 is loosely equivalent to _POSIX_C_SOURCE 200809L */
/* _XOPEN_SOURCE 600 is loosely equivalent to _POSIX_C_SOURCE 200112L */
/* _XOPEN_SOURCE 500 is loosely equivalent to _POSIX_C_SOURCE 199506L */
#if !defined(_XOPEN_SOURCE) && !defined(_POSIX_C_SOURCE)
#if __STDC_VERSION__ >= 199901L
#define _XOPEN_SOURCE 600 /* SUS v3, POSIX 1003.1 2004 (POSIX 2001 + Corrigenda) */
#else
#define _XOPEN_SOURCE 500 /* SUS v2, POSIX 1003.1 1997 */
#endif /* __STDC_VERSION__ */
#endif /* !_XOPEN_SOURCE && !_POSIX_C_SOURCE */
#endif /* JLSS_ID_POSIXVER_H */
Tested on an Ubuntu 12.04 derivative; command line:
gcc -g -O3 -std=c99 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Werror posix2_line_max.c -o posix2_line_max
man getline
Also see http://www.gnu.org/s/libc/manual/html_node/Line-Input.html and the discussion of getline() vs. fgets() vs. gets(). Has been subject on SO more often than I can count as well.
You could use malloc() and expand if necessary, or use the source and look at how a GNU utility does it.
check the line for an '\n', if not exists expand the buffer before you call the next fgets.
POSIX systems have getline which will allocate a buffer for you.
On non-POSIX systems, you can use Chuck B. Falconer's public domain ggets function, which is similar. (Chuck Falconer's website is no longer available, although archive.org has a copy, and I've made my own page for ggets.)

Resources