Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #380515

Re: Call to a function

Path csiph.com!news.mixmin.net!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From Tim Rentsch <tr.17687@z991.linuxsc.com>
Newsgroups comp.lang.c
Subject Re: Call to a function
Date Fri, 19 Jan 2024 12:49:57 -0800
Organization A noiseless patient Spider
Lines 119
Message-ID <86bk9hjbey.fsf@linuxsc.com> (permalink)
References <call-20230922130647@ram.dialup.fu-berlin.de> <20230922081706.858@kylheku.com> <87zg1et4wv.fsf@nosuchdomain.example.com> <86jzs3de3h.fsf@linuxsc.com> <87h6n7tkv4.fsf@nosuchdomain.example.com> <86ttqf2w6p.fsf@linuxsc.com> <uha85r$ha56$1@dont-email.me> <86msw11tpp.fsf@linuxsc.com> <87leblhzud.fsf@nosuchdomain.example.com> <865y1yxiyw.fsf@linuxsc.com> <87fs11e8yz.fsf@nosuchdomain.example.com>
MIME-Version 1.0
Content-Type text/plain; charset=us-ascii
Injection-Info dont-email.me; posting-host="4317632f5246f6fddd21ccc8d476a409"; logging-data="3475972"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+5oIYZrWNQAS0id4jP2R+1HU8kLlp6gNE="
User-Agent Gnus/5.11 (Gnus v5.11) Emacs/22.4 (gnu/linux)
Cancel-Lock sha1:aN1p0Z5BGVMewu8DRP/sS+yK4Us= sha1:YBHT0vfAP8SHx0ZYcPDiD6PLvA4=
Xref csiph.com comp.lang.c:380515

Show key headers only | View raw


Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:

> Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
>
>> Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
>>
>>> The code we're discussing was snipped at some point, so here it
>>> is again:
>>>
>>> int main(void) {
>>>     int obj = 42;
>>>     typedef void func(void);
>>>     if (0) {
>>>         func *fptr = (func*)&obj;
>>>         fptr();
>>>     }
>>> }
>>>
>>> It illustrates the issue that the standard does not define the behavior
>>> of a conversion from an object pointer type to a function pointer type
>>> (other than the special case of a null pointer constant), but does not
>>> make such conversion, expressed as a cast, a constraint violation.
>>>
>>> I asked:  "On what basis do you think a conforming implementation may
>>> reject it?
>>
>> The code is not strictly conforming.
>>
>>> Do you see a syntax rule or constraint that it violates?
>>
>> No.
>>
>>> Do you see some other basis for rejecting it?"
>>
>> Yes.  The conversion expression can be untranslatable on some
>> platforms.  That means any such expression cannot be part of
>> a strictly conforming program.
>
> I disagree.  A conforming implementation could implement a
> conversion of an object pointer to a function pointer that always
> yields a null pointer, or that yields a pointer whose representation
> is derived from the representation of the operand.  The latter is
> typically done for pointer-to-integer or integer-to-pointer
> conversions with mismatched sizes (6.3.2.3 explicitly says that
> integers may be converted to pointers and vice versa).
>
> If, hypothetically, the standard said that an otherwise valid
> program containing a conversion of an object pointer to a function
> pointer type must be successfully translated, then compiler
> implementers could easily find a way to implement such conversions,
> even if the result is not useful.  It is incorrect to claim that
> such a conversion expression may be "untranslatable".

What you mean by translatable is different from what I mean.  Of
course it is possible to produce a sequence of bits that conforms
to the bit-level representation of a function pointer.  The
problem is that it might not be possible to do that in a way that
is sensible, meaningful, or useful.

The contrast with converting between pointers and integers is
helpful here.  Converting a pointer to an integer, even if the
integer type isn't as big as the pointer type, is always
potentially useful, because for example the integer could be used
as a hash function.  Integers also have the nice property that
they are dense (not counting padding bits), so producing any old
integer value will never be problematic.  (Yes I know about the
rule that if the value cannot be represented the behavior is
undefined, but I'm not talking about that.)  Going the other
direction, an integer type whose size is large enough (and almost
always there are such types) can guarantee that converting a
pointer to an integer is invertible.  There is a deeper principle
here:  the addressing structures used in actual hardware use
integers as the basis for addresses.  Converting between integers
and pointers always makes sense at some low level.  An exception
to that rule is elaborate function pointers, which can use very
large structured values to represent a pointer to function.  This
exception is the primary motivation for the C standard saying
that "The result [of converting a pointer to an integer] need not
be in the range of values of any integer type";  in such cases
the behavior is undefined but it is still always allowed to write
an expression asking for such conversions - it is only trying to
execute these expressions that causes a problem.

Note that the C standard reflects the distinction I'm making
here.  The standard specifically specifies that integers may
be converted to pointers, and vice versa.  The standard also
specifically specifies that object pointers may be converted to
other object pointers, and that function pointers may be
converted to other function pointers.  The standard does NOT
specify that function pointers may be converted to object
pointers, or that object pointers may be converted to function
pointers.  This difference corresponds exactly to what I mean
by translatable and untranslatable.  This distinction is not
incidental, accidental, or meaningless.  On the contrary, it is
certainly deliberate, and goes to the heart of the question here.

>> I have no interest in treating you as a student.  I'd be much
>> happier if you would do more thinking for yourself.
>
> I would be happier if you would not assume that I'm not already
> doing that.

It's not assumption but observation.  To give an example, not too
long ago you asked a question in comp.std.c asking about undefined
behavior and indeterminate answers.  I wrote a long posting in
response, basically going through a thorough and systematic review
of the history in different versions of the C standard.  I'm sure
you could have done that yourself if you had tried to do so.

Please note that I'm not saying that you *should* have done that,
only that you *could* have done that.

> Be less arrogant.

I don't think it's arrogant to think or to say that you are
more capable than your comments would otherwise indicate.  If
anything it seems just the opposite, that I have a higher
impression of your abilities than might seem to be the case
to a casual reader.

Back to comp.lang.c | Previous | NextNext in thread | Find similar | Unroll thread


Thread

Re: Call to a function Tim Rentsch <tr.17687@z991.linuxsc.com> - 2024-01-19 12:49 -0800
  Re: Call to a function Lawrence D'Oliveiro <ldo@nz.invalid> - 2024-01-22 03:27 +0000
    Re: Call to a function Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2024-01-21 20:14 -0800
    Re: Call to a function scott@slp53.sl.home (Scott Lurndal) - 2024-01-22 16:36 +0000
      Re: Call to a function Lawrence D'Oliveiro <ldo@nz.invalid> - 2024-01-22 22:05 +0000

csiph-web