clarge-filesfseek

Implicit declaration of function fseeko


I'm trying to use the fseeko function in combination with the GCC-compiler in order to work with files that are larger than 4GiB in C. Now, everything works and I am able to work with files of over 4GiB, but GCC keeps complaining that the fseeko function is implicitly declared. This is a minimal working example of the the source code that generates this message:

#define __USE_LARGEFILE64
#define _LARGEFILE_SOURCE
#define _LARGEFILE64_SOURCE

#include "MemoryAllocator.h"

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <sys/stat.h>

typedef struct BlockReader {
    char* fileName;
    // Total filesize of the file with name fileName in bytes.
    unsigned long long fileSize;
    // Size of one block in bytes.
    unsigned int blockSize;
    // Defines which block was last read.
    unsigned int block;
    // Defines the total amount of blocks
    unsigned int blocks;
} BlockReader;

unsigned char* blockreader_read_raw_block(BlockReader* reader, long startPos, unsigned int length, size_t* readLength) {
    FILE* file = fopen(reader->fileName, "rb");

    unsigned char* buffer = (unsigned char*) mem_alloc(sizeof(unsigned char) * (length + 1));

    FSEEK(file, startPos, 0);
    fclose(file);

    // Terminate buffer
    buffer[length] = '\0';
    return buffer;
}

I cannot find anywhere what header I have to include to fix this warning. The exact warning that GCC gives is this:

src/BlockReader.c: In function ‘blockreader_read_block’:
src/BlockReader.c:80:2: warning: implicit declaration of function ‘fseeko’ [-Wimplicit-function-declaration]
  FSEEK(file, reader->blockSize * reader->block, 0);

Solution

  • If you're using one of the -std options like -std=c99 or -std=c11, these request a fully conforming standard C environment where POSIX interfaces are not exposed by default (exposing them would be non-conforming because they're in the namespace reserved for the application). You need to define _POSIX_C_SOURCE or _XOPEN_SOURCE to an appropriate value to get them. -D_POSIX_C_SOURCE=200809L on the command line, or

    #define _POSIX_C_SOURCE 200809L
    

    in your source file before including any headers, would be the way to do this.

    Also, while this is not your immediate problem, note that __USE_LARGEFILE64, _LARGEFILE_SOURCE, and _LARGEFILE64_SOURCE are all incorrect. The only thing you need to do to get 64-bit off_t is -D_FILE_OFFSET_BITS=64 on the command line or #define _FILE_OFFSET_BITS 64 in your source file before including any headers.