Author Topic: Remove const  (Read 14753 times)

lerno

  • Full Member
  • ***
  • Posts: 247
    • View Profile
Remove const
« on: July 14, 2019, 08:27:14 PM »
Const, as used in C, is often not doing what people think it's doing, and does not offer the protection people think it is protecting.

For pointers, a pointer to a constant struct is saying "using this pointer we will not modify the struct itself (but we may modify what the struct refers to)"

Because of const-ness, functions must guarantee const-ness if they are to be useful. Consider a function foo(int* ptr) it is not allowed to pass a (const int)* pointer to such a function, even if the function does not actually modify the memory region that the pointer points to. For maximal usefulness, functions are therefore forced to declare constness, that is, it should always be foo(i(const int)* ptr)

A valid point is that by declaring an inparameter const it communicates that the function does not modify the parameter, but the injury done by *requiring* could be said to outweigh the benefits.

To try to retain the advantages of const, which avoiding the syntax pollution const can mean, this is a thing C2 could do:

1. A function declares itself const or not const entirely. This is usually a more important distinction than whether each parameter is const or not:

func void foo(int *ptr) const { ... } – will not alter the contents of anything related to the in-pointer. That is, if the signature instead would have been func void foo(int **ptr) const we would not have been allowed to do *ptr = nor **ptr =

The other use that one would retain is declaring global constants.

lerno

  • Full Member
  • ***
  • Posts: 247
    • View Profile
Re: Remove const
« Reply #1 on: July 14, 2019, 08:35:44 PM »

bas

  • Full Member
  • ***
  • Posts: 220
    • View Profile
Re: Remove const
« Reply #2 on: July 15, 2019, 07:29:02 PM »
I was recently struggling with the '
Code: [Select]
const int* const' syntax.  This is not yet supported in C2.
To narrow the discussion, I think only const in combination with pointers are an issue.
Code: [Select]
const i32 Max = 10; is no issue. It is roughly equivalent of using a define in C.

Another note for Alias types in C2:
Code: [Select]
type IntP int*;  // alias type
const IntP ip = a; // is a 'const IntP' ... but weird, 'const IntP' is different from 'const int*'

I always use the keyword const in combination with pointer arguments to indicate that the destination
is not changed. This is indeed more of an API thing. Also I recently had to work with a lot of UEFI
code. This is C code with many macros. One is that they use IN and OUT in all the header files. These
expend to nothing and are used like

Code: [Select]
void example(IN Buffer* buffer, OUT Result* result);

This is also use in other languages like Ada:

Code: [Select]
procedure TEST01 ( In_State : IN VECT_B ; Out_State : IN OUT VECT_B );

I think words like IN/OUT read quite naturally. But to include them in C2, we would have
to decide on what this means with pointers or pointers-to-pointers. I can think of the following use-cases:

  • passing pointer - the dest may not be modified
  • passing pointer - the dest may be modified
  • passing pointer-pointer - the param may be modified, normal out-param case
  • passing multiple-dimension pointer arg - dest may not be modified

The goal here should be making the code more readable (or easier to understand),
not allowing extra compiler-optimizations. Or does anyone know if const unlocks some
very powerfull optimizations?


bas

  • Full Member
  • ***
  • Posts: 220
    • View Profile
Re: Remove const
« Reply #3 on: July 15, 2019, 10:00:01 PM »
(thought experiment using in/out)
Trying to convert const (in combination with pointers) to in/out gives the following:

All examples below as function arguments:

oldnewmeaning
const char*in char*contents may only be read
char*out char*contents may be written, but must be considered uninitialized for reading at moment of call
inout char*contents may be read and written
char**out char**contents may be written, but must be considered uninitialized for reading at moment of call
inout char**contents may be read and written

NOTE that for the char* case, that in the old situation only read+write can be expressed, while in the new
situation, both read-write (inout) AND write-only (out) (or uninitialized reads) can be expressed!


lerno

  • Full Member
  • ***
  • Posts: 247
    • View Profile
Re: Remove const
« Reply #4 on: July 31, 2019, 05:56:33 PM »
D has all of this in the way you write it.