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


Groups > comp.lang.c > #380665 > unrolled thread

Re: Call to a function

Started byTim Rentsch <tr.17687@z991.linuxsc.com>
First post2024-01-22 18:11 -0800
Last post2024-01-22 18:11 -0800
Articles 1 — 1 participant

Back to article view | Back to comp.lang.c

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: Call to a function Tim Rentsch <tr.17687@z991.linuxsc.com> - 2024-01-22 18:11 -0800

#380665 — Re: Call to a function

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2024-01-22 18:11 -0800
SubjectRe: Call to a function
Message-ID<86y1cgg5nb.fsf@linuxsc.com>
I am responding here to two different messages from James Kuyper,
combined for convenience in a single posting.  Each segment
starts with an attribution line naming James and giving his email
address, as would appear in a normal followup, and then gives
a Message-ID for that posting.

Incidentally, both of these message seems to be a response to a
posting (or postings) of mine, but they seem not to be linked
in the usual way that newgroup postings.  I'm not sure how or
why that happened, but I thought I should mention it.

[..first message..]

James Kuyper <jameskuyper@alumni.caltech.edu> writes:
[Message-ID: <uje6vv$gei$1@dont-email.me>]

[This message is missing an attribution line that might have
 been something like the following line]

> Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
>
>> Keith Thompson <Keith.S.T...@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.
>
> The committee has officially ruled in DR 109 that code with undefined
> behavior renders the program not strictly conforming, only if execution
> of that code is an inevitable consequence of running the program.  Not
> only is execution of this code not inevitable, it is in fact impossible
> for it to be executed.

The remarks in DR 109 are irrelevant to what I'm saying.  The
program given above fails to be strictly conforming for reasons
that have nothing to do with undefined behavior.

> I'm curious - on what platform is it impossible, or at least
> difficult, to translate an if(0) block as a no-op?  I'd think that
> simply failing to generate any corresponding machine code would be
> sufficient on most, if not all, platforms.

I hope you realize that this question is quite irrelevant to the
matter being addressed here.

> The code that appeared in DR 109 was not a no-op, but the behavior
> of any program that called the function would be undefined, which
> means that the standard imposes no requirements on its behavior.
> On what platform is it difficult to generate code that has no
> requirements on how it behaves?  I'd think it would be trivial
> translate it as, for instance, the equivalent of
>
> fprintf(stderr, "ISO C does not define the behavior of converting \n"
>     "a pointer to an object into a pointer to a function.\n");
> exit(EXIT_FAILURE);

You seem to think that the problem has to do with how to compile
program text that has undefined behavior.  It doesn't.  Please
see also my response to Keith Thompson's message regarding what
I mean by "translatable".


[..second message..]

James Kuyper <jameskuyper@alumni.caltech.edu> writes:
[in a posting with Message-ID: <ujdgc9$3t0ni$1@dont-email.me>]

> On 2023-11-19 at 02:28 EST, Tim Rentsch wrote:
>
>> James Kuyper <james...@alumni.caltech.edu> writes:
>>
>>> Most fundamentally, what I an hoping to accomplish is to convince
>>> you to answer Keith's question.
>>
>> Consider a C compiler for a machine where function pointers are
>> much bigger than any object pointer type.  Functions might even
>> live in a completely different address space than data (a
>> so-called Harvard architecture).  On such a machine there is no
>> sensible way to change an object pointer into a function pointer,
>> or vice versa.  Naturally the compiler would prefer to choose not
>> to translate any source file that contains such a conversion.
>
> But the standard does not allow such behavior - 

Yes, it does.  There's a flaw in your logic in trying to decide
whether the program is strictly conforming.

> if they wish to
> claim conformance to the C standard, they'll have to do something
> other than what they'd prefer.  Since the code with undefined
> behavior is protected by an if(0), an implementation is not
> required to generate the impossible conversion code, and is
> required to accept the program.

Let me say again that the question of undefined behavior is
not relevant here.  The given program fails to be strictly
conforming for reasons that have nothing to do with undefined
behavior.

>> The C standard doesn't say function pointers may be converted to
>> object pointers, or the other way around.  The obvious thing to
>> do is simply give an error message and forego the translation
>> effort.  It doesn't make sense that the standard would insist
>> that an implementation translate a construct that is nonsensical,
>> not just in a particular case but in every possible case.
>
> I appreciate that you feel that way - but the committee resolved
> DR 109 in conflict with your feeling.

That is your misunderstanding.  The remarks in DR 109 have no
bearing on my conclusions.

> The code referred to by DR
> 109 divided an integer by an integer constant of 0, which wasn't
> even protected by an if(0).  It was the only line in the only
> function defined in that translation unit, which was absolutely
> guaranteed, if function were called, to execute that line.  The
> only reason the committee gave for it being strictly conforming
> was that there was no guarantee that the rest of the program ever
> actually called the function.  But the committee decided that that
> fact was sufficient to make the code, in itself, strictly
> conforming, and the implementation was therefore required to
> accept it.  If the program as a whole did call that function, that
> fact would be sufficient to justify rejecting the whole program,
> but it was not sufficient to justify rejecting that particular
> translation unit.

Your phrasing here is slightly off.  What was actually said is
that

    A conforming implementation must not fail to translate
    a strictly conforming program simply because some
    possible execution of that program would result in
    undefined behavior.

The undefined behavior not being evaluated doesn't guarantee the
program is strictly conforming.  If a program /is/ otherwise
strictly conforming then undefined behavior that is potentially
unevaluated doesn't interfere with that.  Do you see the
difference?  The problem here is that the code in Keith's program
is not strictly conforming, regardless of whether there is
evaluated undefined behavior.

> Basically, code with undefined behavior prevents a program from
> being strictly conforming only if execution of such code is an
> inevitable consequence of starting the program.  If executing that
> code can be avoided, then only a failure to avoid it renders the
> the behavior undefined.  If that failure is not realized at
> compile time, then the implementation must still accept it.

If undefined behavior is unavoidable, then the program is not
strictly conforming, and it need not be accepted.

However, if all undefined behavior is potentially not evalauted,
that does not by itself guarantee that the program is strictly
conforming.  Furthermore you yourself quoted, in another posting,
the relevant sentence from the C standard that bears on the
question of strict conformance.

> If the committee ruled that way on that code, how could you
> possibly expect it to support rejection of this code?

You think the only things that matter in the two programs are
analogous.  They aren't.

>> Converting between function pointers and object pointers isn't
>> like dividing by zero.
>
> True - there's implementations which can meaningfully do such a
> conversion - there's no meaningful way to divide an integer by 0
> (a floating point calculation could reasonably produce infinity,
> if infinity can be represented on that hardware).  Which makes the
> committee's decision on DR 109 even stronger.

Again you miss the point.  The question of undefined behavior
has no bearing on the conclusion.

>> [.. some remarks unrelated to the primary topic ..]
>
> [...]
> However, if you're unable to provide a convincing argument that
> your point of view is correct, then it's a point of view that is,
> quite frankly, of no interest.

I have very little interest in trying to offer an argument
that convinces you.  My conclusions are correct, whether
my comments convince you or not.

[... incidental commentary left out ...]

>> Try compiling Keith's program with gcc -pedantic-errors.  I expect
>> you will find, as I did, that gcc flags the conversion with an
>> error and doesn't produce an output file.  The C standard allows
>> such behavior only if the source file being compiled is not
>> strictly conforming.  I have more confidence in gcc's understanding
>> of the C standard than I do in yours.
>
> I have considerable trust in gcc, but more trust in the actual
> words of the standard.  Where there's a disagreement, I favor the
> actual words of the standard.

The problem is not the words of the C standard but what you think
they mean.

> And, having seen how you interpret the standard, I certainly
> trust my interpretation more than yours.

Of course.  You're living in your own language bubble.  Unlike you,
I calibrate my understanding of what text in the C standard means
by comparing it with other sources, including especially remarks
written or spoken by C standard committee members in other contexts.

>>> Yes, it does.  And I frequently despair of ever figuring out a way
>>> to say what I mean that will be understood as intended by you.
>>> [...]
>>
>> The problem is not me understanding you, but you not understanding
>> me.  Your mental model for how to use and understand natural
>> language is peculiar.  Also rigid and inflexible.  Probably the
>> most troublesome property is that you are focused on argument more
>> than on understanding.  You read the words but don't understand the
>> meaning.  Instead you insist on playing idiosyncratic word games,
>> apparently believing that how you interpret the words is universal
>> and absolute.  It isn't.  Assigning meaning to natural language is
>> inherently a subjective process, not an objective one.  You're a
>> lot better at arguing than you are at listening.  You might want to
>> think about that.
>
> Subjectivity is fine for poetry - but we're talking about a
> standard.  To the extent that the meaning of words is subjective,
> they are unsuitable for use in a standard.  The whole point of the
> standard is to standardize the requirements - that is, to make
> them exactly the same for everyone.  If you have to use subjective
> interpretations to determine what the requirements are, the
> standard has failed the purpose for which it was intended.  An
> implementor could use it's subjective opinion to justify
> implementing C in a way that would be inconsistent with the
> subjective opinion of a user.

I'm sorry you missed the point of what I was saying.

Just one more item.  Here is a quote from the C Rationale document:

  Consequences of the treatment of pointer types in the
  Standard include:

    * [...]

    * Even with an explicit cast, it is invalid to convert
      a function pointer to an object pointer or a pointer
      to void, or vice versa.

Note in particular the word /invalid/.  Not undefined, but
invalid.  What do you suppose is the basis for that statement?
What bearing does it have on the question being discussed?
What do you think the implications are for the various assertions
made during the discussion?

[toc] | [standalone]


Back to top | Article view | comp.lang.c


csiph-web