How to use ftruncate in c99 without warning - c

I want to use ftruncate function in my code. I have to compile with option std=c99. I get warning:
In function ‘test’:
warning: implicit declaration of function ‘ftruncate’ [-Wimplicit-function-declaration]
I tied to find on the Internet any solution which can solve this problem but I don't succeeded in.
I use ftrucnate because I want to clear content of an opened file after I get lock (flock).

Since ftruncate() isn't a standard C function, and you've asked for standards enforcement, you need to define the appropriate feature test macros (see feature_test_macros(7)).
From the ftruncate(2) manpage:
ftruncate():
_BSD_SOURCE || _XOPEN_SOURCE >= 500 ||
_XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED
|| /* Since glibc 2.3.5: */ _POSIX_C_SOURCE >= 200112L
In other words, to expose the ftruncate() function you must define one of these macros, for example:
gcc -c -std=c99 -D_XOPEN_SOURCE=500 myfile.c

FatalError's answer did not work for me. Mostly all you have to do for it to work is:
#include <unistd.h>

Related

Truncate file on Linux with c99

I would like to open a file and set its size so that I can then use mmap to write to it.
I found that I can use function truncate or ftruncate. Unfortunately, when I include <unistd.h> I got error:
error: implicit declaration of function ‘truncate’
I read on Internet that I should use gnu or something like that but this is for school project and we have to compile with -std=c99.
Are there any alternatives?
When you use -std=c99 the C library makes sure that the headers do not declare any symbols that are not reserved/are not defined in the C standard library. Since ftruncate does not belong to the C standard library, being a POSIX extension instead, it is not defined by default.
A POSIX program must, for maximal compatibility, define the _POSIX_C_SOURCE feature test macro, or _XOPEN_SOURCE, with appropriate values, before including the headers.
The feature test macros are listed conveniently on for example Linux manual pages; for ftruncate these would be:
ftruncate():
_XOPEN_SOURCE >= 500
|| /* Since glibc 2.3.5: */ _POSIX_C_SOURCE >= 200112L
|| /* Glibc versions <= 2.19: */ _BSD_SOURCE
i.e. use
#define _XOPEN_SOURCE 500 // (or greater; current is 700)
#include <unistd.h>
or
#define _POSIX_C_SOURCE 200112L // (or greater)
#include <unistd.h>

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.)

Trouble including function declaration for strptime()

Have a time date string I'd like to convert to a tm object. Google tells me the POSIX (but not the C) standard includes a function called strptime() that will do the job.
The man page says it's in <time.h> and that I need to include #define _XOPEN_SOURCE before I include the <time.h> file. Easy enough.
But I still get an implicit declaration warning from the compiler. I opened /usr/include/time.h and found the function declaration:
# ifdef __USE_XOPEN
/* Parse S according to FORMAT and store binary time information in TP.
The return value is a pointer to the first unparsed character in S. */
extern char *strptime (const char *__restrict __s,
const char *__restrict __fmt, struct tm *__tp)
__THROW;
#endif
So it looks like I need #define _USE_XOPEN instead.
Except that doesn't work either. The compiler still isn't seeing the declaration.
Any ideas. I'm using a relatively recent version of Linux (Mint) with gcc 5.4.0.
Converting comments into an answer.
To fix this, your options include using -std=gnu11 instead of -std=c11 on the GCC command line, or using #define _XOPEN_SOURCE 700 or equivalent (e.g. -D_XOPEN_SOURCE=700 on the command line). The 700 identifies POSIX 2008; 600 or 500 identify earlier versions of POSIX or X/Open.
In theory, you could also use _POSIX_C_SOURCE 200809L (see POSIX Compilation environment), but that doesn't expose everything that _XOPEN_SOURCE 700 exposes so it is usually better to use the latter.
Note that the POSIX specification of strptime() is annotated as an XSI extension, which means you must set _XOPEN_SOURCE; setting _POSIX_C_SOURCE alone is not sufficient.
Test code
This test code prints the address of the strptime function; it won't compile if strptime() is not declared.
#define _XOPEN_SOURCE 700
#include <time.h>
#include <stdio.h>
int main(void)
{
printf("%p\n", (void *)strptime);
return 0;
}
That should compile for you with gcc -std=c11 -Wall -c test-strptime.c. If you add -ansi to the options, you reset the standard back to C90. GCC 5.4.0 should default to C11 (effectively -std=gnu11) unless someone did something horrible in the build of GCC that you're using (which is unlikely).
Note that the compiler unsets and then sets __USE_XOPEN based on settings like _XOPEN_SOURCE and trying to set it manually doesn't work reliably.
Position matters
You must specify the #define _XOPEN_SOURCE 700 before the first system header is included (whether included directly or indirectly). If you include a system header before trying to set _XOPEN_SOURCE, the settings have been determined and your subsequent operations are effectively ignored. POSIX says (at the 'compilation environment' link already given):
In the compilation of an application that #defines a feature test macro specified by POSIX.1-2008, no header defined by POSIX.1-2008 shall be included prior to the definition of the feature test macro. This restriction also applies to any implementation-provided header in which these feature test macros are used. If the definition of the macro does not precede the #include, the result is undefined.
One common undefined result is that your attempt to set/change the POSIX version is completely ignored.

dprintf implicit declaration warning

When using dprintf() I'm getting the warning "implicit declaration of dprintf". That tends to mean a necessary file isn't included, but I already included stdio.h, which is supposed to be all that it needs. Is there something else dprintf needs?
The "feature_test_macros" section of the man page explains that to make stdio.h declare dprintf(), you must first #define _POSIX_C_SOURCE 200809L (or higher) before you #include <stdio.h>. The reason for this is that dprintf() was not standardized until POSIX.1-2008, but <stdio.h> needs to continue to work with code written before that, even if that code used its own identifier named "dprintf". (Defining _GNU_SOURCE or _XOPEN_SOURCE would also work on Linux, but _POSIX_C_SOURCE is the best choice for general portability.)
You might need to set some macros. Put on top of the file, before any includes the following
#define _POSIX_C_SOURCE 200809L
#define _GNU_SOURCE
(One of that would be enough but I don't know the GLibC version you use)
You can look up for fprintf() here.
I ran into the same problem and hence I was forced to run on POSIX based machine, I must changed my code, so fprintf() is one of (may be) many options I had.
example :
fprintf(stderr,"file not found");

Compiler doesn't recognize lstat even with the #include's

#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
...
lstat(name, &st);
...
I am using CodeBlocks to write a C program. All the other includes work fine. I checked online and lstat requires the three includes listed at the top of the code, but I still get the error message warning: implicit declaration of function 'lstat' when I try to compile. I do not know what is wrong. If I need to include any extra information to get help, please say.
According to lstat(2):
Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
lstat():
_BSD_SOURCE || _XOPEN_SOURCE >= 500 || _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED
|| /* Since glibc 2.10: */ _POSIX_C_SOURCE >= 200112L
This means you need to define one of these feature test macros to use lstat(2).
So choose one of those feature test macros that makes sense to your code, such as _BSD_SOURCE, and define it in the very beginning (before you include any header file) of your source file, or you could define it on the compiler command line, such as -D_BSD_SOURCE for gcc.
lstat() is not compliant with strict ANSI standard.You should use your compiler flags from
-std=c99 to -std=gnu99 . This would include all the Unix based system.

Resources