What's the best way to minimize the need of run time checks?

Ben Bacarisse ben.usenet at bsb.me.uk
Mon Aug 29 09:31:04 EDT 2016


Steve D'Aprano <steve+python at pearwood.info> writes:

> On Mon, 29 Aug 2016 10:31 pm, Chris Angelico wrote:
>
>> On Mon, Aug 29, 2016 at 10:13 PM, BartC <bc at freeuk.com> wrote:
>>> In C, you can write this:
>>>
>>>  int x;
>>>
>>>  x = 5;
>>>  x = "hello";
>>>
>>> With certain compilers (eg. gcc) you only get a warning. (And since I
>>> don't show warnings to avoid inundation, that seems to compile fine for
>>> me!)
>> 
>> That's because strings, in C, are really pointers-to-char,

They are really arrays of char, but array values convert to pointers to
the first element in so many situations that people end up thinking that
they are pointers.  The trouble is, once you start thinking they really
are pointers-to-char you have a harder time understanding things like
&"hello" and sizeof "hello".

>> and for
>> hysterical raisins, pointers can be assigned to integers with just a
>> warning. (Good code should have an explicit cast here.)

The code is wrong without a cast.  Many compilers, in their default
setting, are very generous about this situation, but the code is as
wrong a C code can be.  The assignment violates a language constraint
and the compiler would be permitted to refuse to generate any code at
all.

Given all that, it's something of an understatement to say that good
code should use a cast (which is always explicit).  (I'd go further and
say that good code should try to avoid doing this at all, and when it
absolutely must, it should use intptr_t rather than int.)

> Let me see if I've got this straight... Bart's second assignment will
> allocate a block of memory at least five bytes in size, stuff the ASCII
> codes for 'h', 'e', 'l', 'l' and 'o' in that block (possibly with a null
> byte at the end?) and then assign x to the address of that block.

Close, but the array of char is not generated by the assignment.  String
literals give rise to arrays with static storage duration (in effect
they exist before the start of the execution).  It will be 6 bytes in
size.

The assignment might do nothing at all because it violates a language
constraint about permitted types in an assignment.  But if it does do
something, a good bet will be to do the usual array to pointer
conversion and then try to convert that pointer to an int for
assignment.

> Am I right?
>
> That's better than my first thought, which was that it would write either
>
>     0x6865  ('he', if int is 16 bits)
>
> or
>
>     0x68656c6c  ('hell', if int is 32 bits)
>
> to x, and either discard the rest of the characters or just blindly write
> them over the top of whatever variable (if any) happens to follow x in
> memory.

Well, your first thought is not actually wrong.  In fact, a compiler
would be allowed to do that since the behaviour of a program that
violates a constraint is undefined by the language standard.  It would
not sell or get used much because people expect the traditional lax
treatment of pointers as integers, but it could do that.

>> Getting inundated with warnings would be a major code smell.
>
> "The low oil warning light in my car was always on, so I put some masking
> tape over it so it wasn't bothering me any more."

Yup.  Gcc lets you put masking tape on (-Wno-int-conversion) but, in
fairness, it also lets you treat all or selected warnings as hard errors
(-Werror=int-conversion).  Unfortunately there is no single option that
treats all serious situations as hard errors, presumably because no two
people agree on what should be considered serious for a particular
architecture.

<snip>
-- 
Ben.



More information about the Python-list mailing list