From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 8022 invoked by alias); 13 Jan 2012 09:32:09 -0000 Received: (qmail 7993 invoked by uid 22791); 13 Jan 2012 09:32:07 -0000 X-SWARE-Spam-Status: No, hits=-2.8 required=5.0 tests=ALL_TRUSTED,AWL,BAYES_00,TW_BG X-Spam-Check-By: sourceware.org Received: from localhost (HELO gcc.gnu.org) (127.0.0.1) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 13 Jan 2012 09:31:54 +0000 From: "burnus at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug fortran/51842] fortran fails if ssize_t is 32-bit on 64-bit host Date: Fri, 13 Jan 2012 09:51:00 -0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: fortran X-Bugzilla-Keywords: wrong-code X-Bugzilla-Severity: normal X-Bugzilla-Who: burnus at gcc dot gnu.org X-Bugzilla-Status: RESOLVED X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Changed-Fields: Message-ID: In-Reply-To: References: X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated Content-Type: text/plain; charset="UTF-8" MIME-Version: 1.0 Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org X-SW-Source: 2012-01/txt/msg01485.txt.bz2 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51842 --- Comment #2 from Tobias Burnus 2012-01-13 09:27:16 UTC --- (In reply to comment #0) > /* The type used of array indices, amongst other things. */ > typedef ssize_t index_type; I just saw that GCC 4.7 uses now: typedef ptrdiff_t index_type; Still, I wonder whether "intptr_t" would be even more correct. Jerry and Mike: What do you think? The change above was committed with the summary "Cleanup memsize types" by Janne on 2011-04-12 as Rev. 172340. http://gcc.gnu.org/git/?p=gcc.git;a=commit;h=c75dca4902ad96d90237f6ab49c368ecb1ff3e52 http://gcc.gnu.org/viewcvs?view=revision&revision=172340 * * * The following has been written before I saw the ptrdiff_t change. It still kind of applies. (In reply to comment #0) > typedef ssize_t index_type; > > might want to assert that sizeof (size_t) == sizeof (ssize_t) If I may nit pick myself: I have no idea why you talk about size_t; neither the front end nor libgfortran uses "size_t" for array indices. In particular, I think that the C99 standard allows size_of(void *) > sizeof(size_t), even if on most systems those should be the same. The front end currently uses an signed integer type of size POINTER_SIZE. That usually matches sizeof(size_t), sizeof(ssize_t), sizeof(intptr_t), and sizeof(ptrdiff_t). However, I think none of those *have to* match sizeof(void *). The question is how to solve this best. The front end uses: #include "tm.h" /* For POINTER_SIZE; cf. gcc/config/. */ /* Choose the integer kind the same size as "void*" for our index kind. */ gfc_index_integer_kind = POINTER_SIZE / 8; gfc_array_index_type = gfc_get_int_type (gfc_index_integer_kind); (Side note: The FE assumes 8 == BITS_PER_UNIT, though in this case the same is assumed in gfc_init_kinds - thus there should not be a real issue.) Searching for suitable signed integer types, one finds: - ssize_t # sys/types.h, POSIX - intprt_t # stdint.h, optional type, C99 - ptrdiff_t # stddef.h, C99 My impression is that "intptr_t" is the best: It is signed, it can store a pointer without information loss, and it is C99. It's not perfect as it is optional (though GCC should provide it) and as the standard allows it to be larger than POINTER_SIZE. Quotes from the standards: intptr_t (from C99): "The following type designates a signed integer type with the property that any valid pointer to void can be converted to this type, then converted back to pointer to void, and the result will compare equal to the original pointer: intptr_t [...] These types are optional." I think most of the time, it has the right size - but the standard also allows it to be larger ... Again C99: "ptrdiff_t which is the signed integer type of the result of subtracting two pointers; size_t which is the unsigned integer type of the result of the sizeof operator" And again: While ptrdiff_t should on the most systems have the same size as POINTER_SIZE, one may not always take the difference and thus it could be (together with size_t) be smaller than POINTER_SIZE. On the other hand, there is also no restriction on the maximal size - thus it could also be larger. POSIX (IEEE Std 1003.1-2001): "ssize_t Used for a count of bytes or an error indication." "* size_t shall be an unsigned integer type." "* blksize_t, pid_t, and ssize_t shall be signed integer types." "The type ssize_t shall be capable of storing values at least in the range [-1, {SSIZE_MAX}]. [...] The implementation shall support one or more programming environments in which the widths of blksize_t, pid_t, size_t, ssize_t, suseconds_t, and useconds_t are no greater than the width of type long."