Bug 38295 - Support pointer difference as constant in static initializer
Summary: Support pointer difference as constant in static initializer
Status: UNCONFIRMED
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 4.3.2
: P3 enhancement
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-11-27 18:19 UTC by Behdad Esfahbod
Modified: 2016-10-12 19:14 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments
label.c (267 bytes, text/plain)
2016-10-12 19:14 UTC, Florian Weimer
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Behdad Esfahbod 2008-11-27 18:19:27 UTC
The feature I'm proposing is not supported by the C standard, so I'm proposing a gcc extension.

I am wondering if it's possible to make the difference of two function pointer be a constant value if the two functions are defined as static and in the same file.  That would allow for function pointer tables that live in .rodata instead of .data.  Something like:

#include <stdio.h>

typedef int (*func_t) (void);

static int func_base (void)
{
  return 0;
}

static int func0 (void)
{
  return 0;
}

static int func1 (void)
{
  return 1;
}

size_t funcs[] = {
  func0 - func_base,
  func1 - func_base
};

int
main (void)
{
  int i;

  for (i = 0; i < 2; i++)
    printf ("%d: %d\n", i, ((func_t)(funcs[i] + func_base))());
}
Comment 1 Andrew Pinski 2008-11-27 18:28:55 UTC
Differences between two different arrays don't make sense really.
Comment 2 Behdad Esfahbod 2008-11-27 18:31:14 UTC
I'm not following.  Why arrays?  Those are pointers, and their difference is known at compile time.
Comment 3 Behdad Esfahbod 2008-11-27 18:32:03 UTC
Oh, I see what you mean.  Yes, I said in my report that this is undefined/unsupported/... according to the C standard.
Comment 4 Andrew Pinski 2008-11-27 18:33:33 UTC
(In reply to comment #2)
> I'm not following.  Why arrays?  Those are pointers, and their difference is
> known at compile time.

Not at compile time really,  the difference is known at link time.
Comment 5 Behdad Esfahbod 2008-11-27 18:35:24 UTC
If the two functions are in the same compilation unit (and static), it's known at compile time, isn't it?
Comment 6 Andrew Pinski 2008-11-27 18:52:02 UTC
(In reply to comment #5)
> If the two functions are in the same compilation unit (and static), it's known
> at compile time, isn't it?

Not always since they could be in different sections via -ffunction-sections or the user put them into different sections.  The layout of the sections is not known until link time.
Comment 7 Andrew Pinski 2008-11-27 18:53:33 UTC
Also the linker could do some branch relaxation which causes the size to be different based on the layout of the functions.
Comment 8 Behdad Esfahbod 2008-11-27 18:55:29 UTC
If they are asked to be put in different sections, sure, it will err.  But doesn't gcc already use relative calls for many static functions in the same unit?

Let me back out:  my request is: add gcc extension to support some way to implement vtables that do not need (many) relocations.
Comment 9 Martin Sebor 2016-04-16 00:51:02 UTC
I'm going to out on a limb and close this as WONTFIX.  First, I don't believe this will or can be implemented for the reasons Andrew mentioned.  The linker also can and some linkers do reorder functions and so the notion of a difference between them doesn't really make sense, either at runtime, but certainly not at  compile time.  Second, there has been no activity on this request in the last 8 years.
Comment 10 Florian Weimer 2016-10-07 19:27:32 UTC
This is already implemented for differences between C && label addresses.  I think there is no compelling reason why this would not work for the addresses of static functions, too.
Comment 11 Florian Weimer 2016-10-12 19:14:36 UTC
Created attachment 39799 [details]
label.c

(In reply to Andrew Pinski from comment #6)
> Not always since they could be in different sections via -ffunction-sections
> or the user put them into different sections.  The layout of the sections is
> not known until link time.

For label differences, the difference is only known at assembly time, not compile time.  So you can really evaluate the constant in GCC, either.  You can even get assembler warnings and incorrect data, as the attached code shows.  It produces an assembler warning for me:

/tmp/ccAMdJhn.s: Assembler messages:
/tmp/ccAMdJhn.s:1237: Warning: value 0x1680 truncated to 0x80

(The reproducer is slightly convoluted to work around bug 77951.)

There might also be targets where label differences are only known at link time, too.