首页 > 解决方案 > 如何使用 -Wstringop-overread 处理特殊指针

问题描述

MPI 函数 MPI_Dist_graph_create_adjacent 允许为某些参数传入特殊的指针值,然后像传入一些默认值填充数组一样处理这些参数。我试图通过指定 access none 属性来消除来自 gcc 11 的相应新警告:

#include <stdio.h>
#include <stdlib.h>

#include <mpi.h>

#define xmpi(rc)                                  \
  do {                                            \
    int err = (rc);                               \
    if (err != MPI_SUCCESS) {                     \
      char msg[MPI_MAX_ERROR_STRING + 1];         \
      int msg_len;                                \
                                                  \
      if (MPI_Error_string(err, msg, &msg_len)    \
          == MPI_SUCCESS){                        \
        msg[msg_len] = '\0';                      \
                                                  \
        fprintf(stderr,                           \
                "Problem in MPI call: %d = %s\n", \
                err, msg);                        \
        MPI_Abort(MPI_COMM_WORLD, 1);             \
      }                                           \
    }                                             \
  } while (0)

#if __GNUC__ >= 11
/* GCC 11 has no means to specify that the special value pointer
 * MPI_UNWEIGHTED does not need to point to something of size > 0 */
extern
int MPI_Dist_graph_create_adjacent(MPI_Comm comm_old,
                                   int indegree,
                                   const int sources[],
                                   const int sourceweights[],
                                   int outdegree,
                                   const int destinations[],
                                   const int destweights[],
                                   MPI_Info info, int reorder,
                                   MPI_Comm *comm_dist_graph)
  __attribute__ ((access (none, 4), access (none, 7)));
#endif

int
main(int argc, char *argv[])
{
  xmpi(MPI_Init(&argc, &argv));
  int rank, size;
  xmpi(MPI_Comm_rank(MPI_COMM_WORLD, &rank));
  xmpi(MPI_Comm_size(MPI_COMM_WORLD, &size));
  printf("Hello world!, I'm rank %d of %d!\n", rank, size);
  {
    MPI_Comm nb_comm;
    enum {
      nhalo = 1,
      nnb = 2 * nhalo,
      no_reorder = 0,
    };
    int nb_ranks[nnb];
    for (size_t i = 0; i < nhalo; ++i) {
      nb_ranks[nhalo - i - 1] = (rank - i + size)%size;
      nb_ranks[nhalo + i] = (rank + i)%size;
    }
    int rc = MPI_Dist_graph_create_adjacent(
      MPI_COMM_WORLD, nnb, nb_ranks, MPI_UNWEIGHTED, nnb,
      nb_ranks, MPI_UNWEIGHTED, MPI_INFO_NULL, no_reorder,
      &nb_comm);
    xmpi(rc);
    xmpi(MPI_Comm_free(&nb_comm));
  }
  xmpi(MPI_Finalize());
  return EXIT_SUCCESS;
}

但这似乎对这种情况无济于事:

$ mpicc -Wall -o dist_graph_mini dist_graph_mini.c
dist_graph_mini.c: In function 'main':
dist_graph_mini.c:61:14: warning: 'MPI_Dist_graph_create_adjacent' reading 4 bytes from a region of size 0 [https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wstringop-overread-Wstringop-overread]
   61 |     int rc = MPI_Dist_graph_create_adjacent(
      |              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   62 |       MPI_COMM_WORLD, nnb, nb_ranks, MPI_UNWEIGHTED, nnb,
      |       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   63 |       nb_ranks, MPI_UNWEIGHTED, MPI_INFO_NULL, no_reorder,
      |       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   64 |       &nb_comm);
      |       ~~~~~~~~~
dist_graph_mini.c:61:14: note: referencing argument 4 of type 'const int *'
dist_graph_mini.c:61:14: warning: 'MPI_Dist_graph_create_adjacent' reading 4 bytes from a region of size 0 [https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wstringop-overread-Wstringop-overread]
dist_graph_mini.c:61:14: note: referencing argument 7 of type 'const int *'
dist_graph_mini.c:29:5: note: in a call to function 'MPI_Dist_graph_create_adjacent'
   29 | int MPI_Dist_graph_create_adjacent(MPI_Comm comm_old,
      |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

在我的系统上 MPI_UNWEIGHTED 被简单地定义为文字 2:

#define MPI_UNWEIGHTED           ((int *) 2)

在这个系统(Linux x86_64)上,它不能引用一个有效的对象,但这也是 MPI 可以特别检测和处理的东西。因此,虽然上面显然不是可移植的 C,但我真的很想继续使用这个值,而不是被警告。

标签: cgccmpiopenmpi

解决方案


推荐阅读