奇怪的全局变量行为,一旦变量名称发生变化,问题就会消失

ali*_*n01 1 c variables overwrite mpi name-conflict

在我的大学练习中,我遇到了变量的奇怪行为.

/* Main parameters                                                          */
double sizeX, sizeY;      /* Size of the global domain                      */
int nPartX, nPartY;       /* Particle number in x, y direction              */
int nPart;                /* Total number of particles                      */
int nCellX, nCellY;       /* (Global) number of cells in x, y direction     */
int steps;                /* Number of timesteps                            */
double dt;                /* Stepsize for timesteps                         */
int logs;                 /* Whether or not we want to keep logfiles        */

void ReadInput(const char *fname)
{
  FILE *fp;
  char c;

  Debug("ReadInput", 0);
  if(rank == 0)
  {
    fp = fopen(fname, "r");
    if(!fp) Debug("Cannot open input file", 1);
    if(fscanf(fp, "sizeX: %lf\n", &sizeX) != 1) Debug("sizeX?",  1);
    if(fscanf(fp, "sizeY: %lf\n", &sizeY) != 1) Debug("sizeY?",  1);
    if(fscanf(fp, "nPartX:%i\n", &nPartX) != 1) Debug("nPartX?", 1);
    if(fscanf(fp, "nPartY:%i\n", &nPartY) != 1) Debug("nPartY?", 1);
    if(fscanf(fp, "nCellX:%i\n", &nCellX) != 1) Debug("nCellX?", 1); //read value is 10
    if(fscanf(fp, "nCellY:%i\n", &nCellY) != 1) Debug("nCellY?", 1);    
    if(fscanf(fp, "steps: %li\n", &steps) != 1) Debug("steps?",  1);    
//here the nCellX variable value 10 is changed somehow to 0
    if(fscanf(fp, "dt:    %lf\n", &dt)    != 1) Debug("dt?",     1);
    if(fscanf(fp, "logs:  %c\n",  &c)     != 1) Debug("logs?",   1);
    logs = (c == 'y');
    fclose(fp);
  }

  printf("(%i) reporting in...\n", rank);

  MPI_Bcast(&sizeX, 1, MPI_DOUBLE, 0, grid_comm);  
  MPI_Bcast(&sizeY, 1, MPI_DOUBLE, 0, grid_comm);
  MPI_Bcast(&nPartX,1, MPI_INT,    0, grid_comm);  
  MPI_Bcast(&nPartY,1, MPI_INT,    0, grid_comm);
  MPI_Bcast(&nCellX,1, MPI_INT,    0, grid_comm);
  MPI_Bcast(&nCellY,1, MPI_INT,    0, grid_comm);
  MPI_Bcast(&steps, 1, MPI_INT,    0, grid_comm);
  MPI_Bcast(&dt,    1, MPI_DOUBLE, 0, grid_comm);
  MPI_Bcast(&logs,  1, MPI_INT,    0, grid_comm);
  nPart = nPartX * nPartY;
  dt2 = dt * dt;
}
Run Code Online (Sandbox Code Playgroud)

老师和我得出结论,如果我们将变量名称从"nCellX"更改为"nCellX_2",问题就会消失,代码会按预期工作.另一个有趣的事情是,只有这个单一的全局变量有这个问题,其他变量才能正常工作.我想知道是否有人遇到过这种类型的问题.任何指南/解释将不胜感激.

如果这个问题不够清楚,请告诉我,如果需要完整代码,我也可以提供.通常,代码是粒子在单元格中的并行算法.

Mar*_*ins 5

以下代码行可能会导致问题:

if(fscanf(fp, "steps: %li\n", &steps) != 1) Debug("steps?",  1);
Run Code Online (Sandbox Code Playgroud)

%li表示一个长整数,可能是64位,steps而是a int,可能是32位.格式说明符应该%i代替%li.

是否存在实际问题取决于环境(例如,如果构建64位应用程序,则很可能是一个问题).如果存在64位与32位不匹配,则fscanf调用将覆盖内存并可能销毁steps内存布局中的任何变量(可能是nCellX).请注意,使用-Wall选项应该警告您这种情况.为什么将nCellX的名称更改为不同的名称应掩盖问题尚不清楚,但似乎更改名称可能会导致内存中变量布局的更改; 我怀疑C标准是不允许的(虽然我没看过).

  • @Shahbaz,是的,它可以.如果存在"未定义行为"的类型不匹配,即使发生任何事情也可能发生. (2认同)