[Mpi-forum] Giving up on C11 _Generic

HOLMES Daniel d.holmes at epcc.ed.ac.uk
Thu Aug 8 06:42:13 CDT 2019

Hi JeffH,

After a brief search that I never knew was necessary, I find that “all” is smaller than “everything” in clang world.

So, my question “why isn’t -Wconversion implied by -Wall?” might have an astonishing answer.

The resulting workflow is then:
1) notice the symptoms of a bug in the output/effect of the code
2) re-compile with -Weverything -Wno-c++98-compat -Wno-c++-compat
3) re-compile with -Weverything -Wno-c++98-compat -Wno-c++-compat -Wno-<other-conflicts>
4) re-compile with -Weverything -Wno-c++98-compat -Wno-c++-compat -Wno-<other-conflicts> -Wno-<unrelated>
5) address all remaining warnings by changing code
Experience and repeated exposure would permit combining steps 2-4.

This is documented, once you know to go look for it. However, it was not obvious to me that looking beyond “-Wall” was needed.

Whilst I agree wholeheartedly that “incorrect programs are incorrect”, I think designers of interfaces/standards have some responsibility to select a design that makes it easy to discover incorrect usage over one that makes it hard. Ideally, a design should be selected that makes it hard to form incorrect usage rather than one that makes misuse easy.

Dr Daniel Holmes PhD
Architect (HPC Research)
d.holmes at epcc.ed.ac.uk<mailto:d.holmes at epcc.ed.ac.uk>
Phone: +44 (0) 131 651 3465
Mobile: +44 (0) 7940 524 088
Address: Room 2.09, Bayes Centre, 47 Potterrow, Central Area, Edinburgh, EH8 9BT
The University of Edinburgh is a charitable body, registered in Scotland, with registration number SC005336.

On 7 Aug 2019, at 21:14, Jeff Hammond via mpi-forum <mpi-forum at lists.mpi-forum.org<mailto:mpi-forum at lists.mpi-forum.org>> wrote:

I don't care that much about C11 _Generic, which is why I have always focused on a C99 solution to the large-count problem, but I disagree with your reasons for abandoning it.

"silently truncated at run time" is trivially addressed with -Wconversion or -Wshorten-64-to-32.  The example program below is addressed by this.

$ clang -Wshorten-64-to-32 -c truncation.c
truncation.c:10:9: warning: implicit conversion loses integer precision: 'long long' to 'int' [-Wshorten-64-to-32]
    ~~~ ^
1 warning generated.

$ gcc-9 -Wconversion -c truncation.c
truncation.c: In function 'main':
truncation.c:10:9: warning: conversion from 'long long int' to 'int' may change value [-Wconversion]
   10 |     foo(i);
      |         ^

$ icc -Wconversion -c truncation.c
truncation.c(10): warning #1682: implicit conversion of a 64-bit integral type to a smaller integral type (potential portability problem)

In any case, incorrect programs are incorrect.  It is a quality-of-implementation issue whether C compilers and MPI libraries detect incorrect usage.  We have never designed MPI around people who can't follow directions and we should not start now.


On Wed, Aug 7, 2019 at 6:59 AM Jeff Squyres (jsquyres) via mpi-forum <mpi-forum at lists.mpi-forum.org<mailto:mpi-forum at lists.mpi-forum.org>> wrote:

Due to the possibility of silently introducing errors into user applications, the BigCount WG no longer thinks that C11 _Generic is a good idea.  We are therefore dropping that from our proposal.  The new proposal will therefore essentially just be the addition of a bunch of MPI_Count-enabled "_x" functions in C, combined with the addition of a bunch of polymorphic MPI_Count-enabled interfaces in Fortran.


Joseph Schuchart raised a very important point in a recent mailing thread: the following C/C++ code does not raise a compiler warning:

#include <stdio.h>

static void foo(int j) {
    printf("foo(j) = %d\n", j);

int main(int argc, char *argv[]) {
    /* 8589934592LL == 2^33 */
    long long i = 8589934592LL + 11;
    return 0;

If you compile and run this program on a commodity x86-64 platform, a) you won't get a warning from the compiler, and b) you'll see "11" printed out.  I tried with gcc 9 and clang 8 -- both with the C and C++ compilers.  I even tried with "-Wall -pedantic".  No warnings.

This is because casting from a larger int type to a smaller int type is perfectly valid C/C++.

Because of this, there is a possibility that we could be silently introducing errors into user applications.  Consider:

1. An application upgrades its "count" parameters to type MPI_Count for all calls to MPI_Send.
   --> Recall that "MPI_Count" already exists in MPI-3.1, and is likely of type (long long) on commodity x86-64 platforms
2. The application then uses values in that "count" parameter that are greater than 2^32.

If the user's MPI implementation and compiler both support C11 _Generic, everything is great.

But if either the MPI implementation or the compiler do not support C11 _Generic, ***the "count" value will be silently truncated at run time***.

This seems like a very bad idea, from a design standpoint.

We have therefore come full circle: we are back to adding a bunch of "_x" functions for C, and there will be no polymorphism (in C).  Sorry, folks.

Note that Fortran does not have similar problems:

1. Fortran compilers have supported polymorphism for 20+ years
2. Fortran does not automatically cast between INTEGER values of different sizes

After much debate, the BigCount WG has decided that C11 _Generic just isn't worth it.  That's no reason to penalize Fortran, though.

Jeff Squyres
jsquyres at cisco.com<mailto:jsquyres at cisco.com>

mpi-forum mailing list
mpi-forum at lists.mpi-forum.org<mailto:mpi-forum at lists.mpi-forum.org>

Jeff Hammond
jeff.science at gmail.com<mailto:jeff.science at gmail.com>
mpi-forum mailing list
mpi-forum at lists.mpi-forum.org<mailto:mpi-forum at lists.mpi-forum.org>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mpi-forum.org/pipermail/mpi-forum/attachments/20190808/018bb65a/attachment-0001.html>

More information about the mpi-forum mailing list