我对FreeBSD刚起步,目前正在将终端仿真库从Linux移植到FreeBSD和Mac OS。我遇到了一些非常奇怪的行为,以至于当我通过指针将结构传递给子例程时,成员值被清零。在Linux或Mac OS上不会发生这种情况。编译器是GCC还是Clang也不重要。

我已经确认在调用子例程和通过指针传递父结构之前,成员值是正确的。

我已经在Linux和Mac OS上测试了相同的代码,但它们没有出现问题。

我已经在FreeBSD的GCC和Clang之间切换了,这似乎没有任何效果。

我考虑过可能发生堆栈粉碎,但似乎不太可能,因为ulimit显示Linux上的堆栈大小为8M,而在FreeBSD上,堆栈大小更大(524 MB)。我也曾尝试使用-fstack-protector-strong进行编译,但这些都不重要。

#include "vterm.h"
#include "vterm_private"  // vterm_t and vterm_desc_t defined here

void vterm_cursor_move_backward(vterm_t* vterm) {
  vterm_desc_t* v_desc = NULL;
  int min_row;
  int idx;

  // idx = vterm_buffer_get_active(vterm);
  idx = 0;  // hard set to 0 just for debugging
  v_desc = &vterm->vterm_desc[idx];

  // printf() will display a value of zero
  printf("%d\n\r", v_desc->ccol);
  fflush(stdout);
}

void vterm_interpret_ctrl_char(vterm_t* vterm, const char* data) {
  vterm_desc_t *v_desc = NULL;
  int idx;
  char verb;

  // idx = vterm_buffer_get_active(vterm);
  idx = 0;  // hard set to 0 just for debugging
  v_desc = &vterm->vterm_desc[idx];

  verb = data[0];

  switch (verb) {
    case '\b': {
      // the following printf will print a positive number
      printf("%d\n\r", v_desc->ccol);
      fflush(stdout);
      vterm_cursor_move_backward(vterm);
      break;
    }
  }
}


我希望v_desc-> ccol的值在两个函数中都相同。 Godbolt Link Github Link参见文件vterm_ctrl_char.c和vterm_cursor.c

最佳答案

经过无数小时的调试后,我发现vterm_desc_t结构中的数据实际上已移动,导致成员值设置为零。虽然,ncurses头文件通过vterm_private.h包含在FreeBSD上,但这似乎无关紧要。 GCC和Clang都乐于以错误/不完整的对齐方式静默编译vterm_cursor.c转换单元。

我建议任何遇到问题的人尝试单独编译每个翻译单元,这就是我发掘出来的方式。例如gcc -S vterm_cursor.c

谢谢所有看过这个的人。

关于c - 通过指针传递对象时丢失成员值,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57614610/

10-12 16:05