public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/59905] New: Unfriendly abort when calling a fucntion via a function pointer cast
@ 2014-01-22 12:41 nisse at lysator dot liu.se
  2014-01-29 10:11 ` [Bug c/59905] " rguenth at gcc dot gnu.org
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: nisse at lysator dot liu.se @ 2014-01-22 12:41 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59905

            Bug ID: 59905
           Summary: Unfriendly abort when calling a fucntion via a
                    function pointer cast
           Product: gcc
           Version: 4.7.2
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: nisse at lysator dot liu.se

Created attachment 31918
  --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=31918&action=edit
Example program

Some background:

In GNU nettle, I use function casts between function types differing in
the type of some pointer arguments. E.g.,

  struct s;

  int foo(struct s *);

  typedef int func_t(void *);

  func_t *f = (func_t *) foo;

Later on, f will be called with an argument of type void *, which
actually is a pointer to a valid struct s, but cast to void *.

I'm aware this is not strictly valid C, but I expect it to work on
virtually all C implementations, because struct s may well be an
incomplete type, and hence the calling conventions cannot reasonably
depend on it's actual definition. If it matters, I could replace void
* above by struct anything *, where struct anything is a different
incomplete type, not defined in any compilation unit ever.

(If you know any examples of architectures, supported by gcc or
otherwise, where calling conventions make this break, I'd be curious
to know about it).

And I think this style is fairly common in object oriented C code. The
closest alternatives, if one wants to stick to the C specification, is
to either skip type checking altogether, always using void * for the
function arguments, and casting when used. Or have do-nothing wrapper
functions like

  int foo(struct s *);
  int foo_wrapper(void *p) { return foo(p); }

This would typically compile to a single jump instruction, but I don't
think the wrapper can be eliminated completely by an optimizing C
compiler, because it is required that pointer comparison foo ==
foo_wrapper gives a false result.

And the reason I care is that I have a library with fairly a large
number of functions, which I want to let applications call either
directly, *with* strong type checking of all arguments, or call via an
abstraction using function pointers and void * instead of the real
struct type pointer, for state/context arguments.

This style seems to work fine with gcc. The surprise is when you call
a function via a cast like this, *without* first storing it a
variable. Like

  struct s;
  ((func_t *)foo)(&s);

Here, the compiler issues a warning, and replaces the call by a call
to abort(). I'm attaching a complete example program. With gcc-4.7.2,
on Debian GNU/linux x86_64, this is what happens (and it's the same
with gcc-4.4 and gcc-4.6)

  $ gcc func-cast.c 
  func-cast.c: In function ‘main’:
  func-cast.c:33:41: warning: function called through a non-compatible type
[enabled by default]
  func-cast.c:33:41: note: if this code is reached, the program will abort
  $ ./a.out
  foo x: 1
  bar x (var): 2
  Illegal instruction (core dumped)

I find this behaviour a bit obnoxious... I understand you might just
say that this is bad code and gcc could emit an exec("nethack") if it
wanted to. I think the current gcc behaviour is bad, in particular as
default behavior, because

1. Generating a call to abort is generally unfriendly.

2. I expect that

     f = expr; f(...);

   and

     (expr)(...);

   should behave in roughly the same way for all possible expr, at
   least as long as f and expr have the same type, so the assignment
   itself doesn't imply any type conversion.

3. I think the compiler should in general treat explicit casts in the
   source code as meaning "I think I know what I'm doing, please don't
   complain about it".
>From gcc-bugs-return-441199-listarch-gcc-bugs=gcc.gnu.org@gcc.gnu.org Wed Jan 22 12:54:20 2014
Return-Path: <gcc-bugs-return-441199-listarch-gcc-bugs=gcc.gnu.org@gcc.gnu.org>
Delivered-To: listarch-gcc-bugs@gcc.gnu.org
Received: (qmail 20837 invoked by alias); 22 Jan 2014 12:54:20 -0000
Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm
Precedence: bulk
List-Id: <gcc-bugs.gcc.gnu.org>
List-Archive: <http://gcc.gnu.org/ml/gcc-bugs/>
List-Post: <mailto:gcc-bugs@gcc.gnu.org>
List-Help: <mailto:gcc-bugs-help@gcc.gnu.org>
Sender: gcc-bugs-owner@gcc.gnu.org
Delivered-To: mailing list gcc-bugs@gcc.gnu.org
Received: (qmail 20807 invoked by uid 48); 22 Jan 2014 12:54:17 -0000
From: "lode.leroy at gmail dot com" <gcc-bugzilla@gcc.gnu.org>
To: gcc-bugs@gcc.gnu.org
Subject: [Bug bootstrap/56645] libgcc /configure identifies non-existing /lib/cpp as preprocessor on Mingw
Date: Wed, 22 Jan 2014 12:54:00 -0000
X-Bugzilla-Reason: CC
X-Bugzilla-Type: changed
X-Bugzilla-Watch-Reason: None
X-Bugzilla-Product: gcc
X-Bugzilla-Component: bootstrap
X-Bugzilla-Version: 4.8.0
X-Bugzilla-Keywords:
X-Bugzilla-Severity: normal
X-Bugzilla-Who: lode.leroy at gmail dot com
X-Bugzilla-Status: WAITING
X-Bugzilla-Priority: P3
X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org
X-Bugzilla-Target-Milestone: ---
X-Bugzilla-Flags:
X-Bugzilla-Changed-Fields: cc
Message-ID: <bug-56645-4-mYmC3WREg8@http.gcc.gnu.org/bugzilla/>
In-Reply-To: <bug-56645-4@http.gcc.gnu.org/bugzilla/>
References: <bug-56645-4@http.gcc.gnu.org/bugzilla/>
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: 7bit
X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/
Auto-Submitted: auto-generated
MIME-Version: 1.0
X-SW-Source: 2014-01/txt/msg02341.txt.bz2
Content-length: 513

http://gcc.gnu.org/bugzilla/show_bug.cgi?idV645

Lode Leroy <lode.leroy at gmail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |lode.leroy at gmail dot com

--- Comment #3 from Lode Leroy <lode.leroy at gmail dot com> ---
cpp is not found by configure: which cpp returns '/mingw/bin/cpp'

/lib/cpp happens to be the last one tried in
libgcc/configure:3859


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2024-04-11  1:14 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-01-22 12:41 [Bug c/59905] New: Unfriendly abort when calling a fucntion via a function pointer cast nisse at lysator dot liu.se
2014-01-29 10:11 ` [Bug c/59905] " rguenth at gcc dot gnu.org
2014-01-29 11:22 ` rguenth at gcc dot gnu.org
2014-01-30 14:17 ` rguenth at gcc dot gnu.org
2014-01-30 14:53 ` rguenth at gcc dot gnu.org
2023-05-12 21:47 ` pinskia at gcc dot gnu.org
2024-04-11  1:14 ` [Bug c/59905] Unfriendly abort when calling a function " pinskia at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).