c - 如何使用 -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,但我真的很想继续使用这个值,而不是被警告。
解决方案
推荐阅读
- java - Apache Nifi:从 Java 应用程序执行/触发 Nifi 处理器
- android - android studio 4.0 无法访问 com.example.projectname.javaname
- javascript - 我可以在 javascript 中定义打印驱动程序吗?
- c# - 如何在 Visual Studio Code 中调试 .net 核心应用程序?
- python - 检查字符串是否有相似的模式
- python - 一个数的 Python 因数
- python - 将循环应用于 CSV 文件的列
- python - 比较两个列表,如果列表一中的条目与列表 2 中的条目相差 x 个字符,则将列表一条目替换为列表二条目
- r - 计算向量中出现相似文本值的次数
- reactjs - 当我们在反应中导航到我们的页面之一时如何清除我们的应用程序历史记录