[GRASS-dev] off_t question

Hi,

when compiling diglib I am getting several warnings like

format ‘%lld’ expects argument of type ‘long long int’, but argument 4 has type ‘off_t’ [-Wformat]

I am running Debian Unstable 64bit.

With a sample app

#include <stdio.h>
#include <sys/types.h>

int main(void) {
off_t blah;

return 0;
}

I am getting

gcc -E sizes.c | grep __off_t | grep typedef
typedef long int __off_t;
typedef __off_t off_t;

and

gcc -E sizes.c -D_FILE_OFFSET_BITS=64 | grep off_t
typedef __off64_t off_t;

This seems to be OK. Trying to understand why %lld causes these warnings.

Martin


Martin Landa <landa.martin gmail.com> * http://geo.fsv.cvut.cz/~landa

2013/4/1 Martin Landa <landa.martin@gmail.com>

[...]

gcc -E sizes.c -D_FILE_OFFSET_BITS=64 | grep off_t
typedef __off64_t off_t;

the reason is that __off64_t is defined on my machine (shouldn't be
long long int?) also as

typedef long int __off64_t;

So PRI_OFF_T in gis.h should be probably fixed.

Martin

--
Martin Landa <landa.martin gmail.com> * http://geo.fsv.cvut.cz/~landa

Martin Landa wrote:

2013/4/1 Martin Landa <landa.martin@gmail.com>

[...]

> gcc -E sizes.c -D_FILE_OFFSET_BITS=64 | grep off_t
> typedef __off64_t off_t;

the reason is that __off64_t is defined on my machine (shouldn't be
long long int?) also as

typedef long int __off64_t;

So PRI_OFF_T in gis.h should be probably fixed.

What should be fixed is this part in Grass.make:

  # crude hack for vector LFS, LFS_FLAGS should be set by configure
  ifdef USE_LARGEFILES
  LFS_CFLAGS = -D_FILE_OFFSET_BITS=64
  endif

_FILE_OFFSET_BITS shouldn't be set on a system with a 64-bit "long".

The main problem is that the LFS tests were taken wholesale from
cdrtools and no-one understands them.

On the plus side, the warnings don't indicate a real problem. They
arise because C considers "long int" and "long long int" to be
distinct types even when they have the same size and representation.

--
Glynn Clements <glynn@gclements.plus.com>

Hi,

2013/4/2 Glynn Clements <glynn@gclements.plus.com>:

What should be fixed is this part in Grass.make:

        # crude hack for vector LFS, LFS_FLAGS should be set by configure
        ifdef USE_LARGEFILES
        LFS_CFLAGS = -D_FILE_OFFSET_BITS=64
        endif

_FILE_OFFSET_BITS shouldn't be set on a system with a 64-bit "long".

The main problem is that the LFS tests were taken wholesale from
cdrtools and no-one understands them.

thanks for clarification, what kind of fix do you suggest?

On the plus side, the warnings don't indicate a real problem. They
arise because C considers "long int" and "long long int" to be
distinct types even when they have the same size and representation.

Just note that diglib is using PRI_OFF_T for off_t formatting, in
vector lib is used mostly %ld.

Martin

--
Martin Landa <landa.martin gmail.com> * http://geo.fsv.cvut.cz/~landa

Martin Landa wrote:

> What should be fixed is this part in Grass.make:
>
> # crude hack for vector LFS, LFS_FLAGS should be set by configure
> ifdef USE_LARGEFILES
> LFS_CFLAGS = -D_FILE_OFFSET_BITS=64
> endif
>
> _FILE_OFFSET_BITS shouldn't be set on a system with a 64-bit "long".
>
> The main problem is that the LFS tests were taken wholesale from
> cdrtools and no-one understands them.

thanks for clarification, what kind of fix do you suggest?

I believe that the intended usage is to add the appropriate #undef
directives to config.h.in, which would either be converted to #define
directives or commented out.

I can't verify that this works for _FILE_OFFSET_BITS as I don't have
access to a 32-bit Linux system.

However, it works for _LARGEFILE_SOURCE, where the #undef (which is
inside a "#if 0") is normally commented out but converted to a #define
if -ansi as added to CFLAGS (which will disable fseeko/ftello by
default).

There are three distinct macros involved:

_LARGEFILE_SOURCE is used to enable fseeko() and ftello(). This is
enabled automatically if _XOPEN_SOURCE>=500 (defining _GNU_SOURCE sets
_XOPEN_SOURCE to 700; gcc defines _GNU_SOURCE if you don't use -ansi
or -std=).

_FILE_OFFSET_BITS is set to 64 to have glibc make off_t a 64-bit type,
even on 32-bit systems.

_LARGE_FILES is apparently an AIX-ism.

It appears that earlier versions of the macros would also try defining
_XOPEN_SOURCE and/or _XOPEN_SOURCE_EXTENDED to get the fseeko/ftello
declarations, but that isn't the case for the versions in our
aclocal.m4.

Having said all that, one problem with using config.h is that gis.h
includes it *after* stdio.h, while those macros need to be defined
before stdio.h is included.

> On the plus side, the warnings don't indicate a real problem. They
> arise because C considers "long int" and "long long int" to be
> distinct types even when they have the same size and representation.

Just note that diglib is using PRI_OFF_T for off_t formatting, in
vector lib is used mostly %ld.

That will break on 32-bit systems with LFS enabled, as %ld will expect
a 32-bit value while an off_t will be a 64-bit value. As printf() etc
are variadic, the compiler doesn't know the correct argument types and
can't perform implicit conversions (the __attribute__((format,...)) is
only used for warnings; it won't result in conversions).

If the off_t is the final argument, it will just result in an
incorrect value (the bottom 32 bits will be used on little-endian
systems, the top 32 bits on big-endian systems).

If there are additional arguments after the off_t, everything will be
out of sync, i.e. the first 4 bytes of the off_t will be used for the
%ld, the last 4 bytes will be treated as the following argument (part
of it).

--
Glynn Clements <glynn@gclements.plus.com>