[Mpi-22] Borderline ticket #107: Types of predefined constants in Appendix A

Dave Goodell goodell at [hidden]
Mon Aug 3 16:00:13 CDT 2009



On Aug 3, 2009, at 12:36 PM, Erez Haba wrote:

> This might be nitpicking but wouldn't that force implementation to  
> typecast their definition of error codes? For example,
>
>        #define MPI_ERR_BUFFER 0
>
> Is not a correct definition with the proposed change, because it is  
> not typed.

I think that the "Constants with the type const int may also be  
implemented as literal integer constants substituted by the  
preprocessor" bit on lines 23-24 helps implementors realize that they  
don't need to insert a cast here.  Also, the type of the integer  
constant 0 is typed as the first integer type in {int, long int, long  
long int} that can express the value, which is required to be int in  
this particular case.

> Thus, it needs to change to
>
> #define MPI_ERR_BUFFER (int)0   // you don't really need to define  
> it as (const int)0
>
> as a result the following statement
>
>        short x = MPI_ERR_BUFFER;
>
> which compiled correctly before, would break with this change.

To the best of my knowledge this is still perfectly legitimate C.   
Section 6.5.16.1 of my copy of the C99 standard seems to corroborate  
this:

-------8<--------
Semantics

2 In simple assignment (=), the value of the right operand is  
converted to the type of the assignment expression and replaces the  
value stored in the object designated by the left operand.
-------8<--------

GCC doesn't give a warning for this assignment, even when you add a  
bunch of warning flags.  It does warn if the value is something too  
large for the short type (like 0xdeadbeef), although of course only  
for direct assignments like this when the compiler still knows the  
origin of the value.  Does the Microsoft compiler behave differently?

> Second comment.
>
> Adding the 'const' modifier to all types is very confusing imho. I  
> understand that it meant to make it clear that the values are  
> constants and should not change, but still is very confusing.
>
> For example,
>
>        C Type: void * const
>        MPI_BOTTOM
>
> This means that the value of MPI_BOTTOM is constant and not the  
> memory it points to. however at first look you might think that it's  
> the later. (if it was, it would break any application that uses it  
> because the API's do not take a pointer to const void)

I'm not sure that there's a lot we can do if people can't properly  
read cv-qualified C types.  This is a standards document, not a  
tutorial.  I don't think that this is intentionally misleading or  
difficult to read.

> In any case implementers should define MPI_BOTTOM as
>
>        #define MPI_BOTTOM (void*)0
>
> Rather than
>
>        #define MPI_BOTTOM (void* const)0
>
> As the value is constant and you don't need to add the const modifier.

The reason you don't really need the const here is that casts create  
rvalues. So it has the same effect as a cast to the unqualified type.   
This, combined with the constant initializer rule in MPI-2.1 section  
2.5.4, is one reason that choosing "const int" as the type for these  
constants is debatable.

> Note that the 'constness' of these values is already stated in the  
> title of the section '19.1.1 Defined Constants'

I don't agree.  The semantic constness of these constants is implied  
by the title, but not the specific language implementation constness.   
In the standard we could say "X, Y, and Z are constants (their values  
never change) with the exact type `int'".  Depending on the exact uses  
with the rest of the API this would be perfectly valid, although we  
might lose some error checking assistance from C compilers.

The title together with MPI-2.1 section 2.5.4 indicates that most of  
these are compile-time constants that may be used for initialization,  
so you could say that the constness doesn't matter since these may  
never be stored in link-time constant variables.  However using  
"const" as a way of indicating that these constants are "non- 
lvalue" (and in particular, "non-(modifiable lvalue)") is fine by me.

-Dave



More information about the Mpi-22 mailing list