ncurses mvaddch() 光标移动可能是一个错误?

ncurses mvaddch() cursor movement a possible bug?

代码:

#include <ncurses.h>

int main(int argc, char **argv)
{
    initscr();
    noecho();
    cbreak();


    mvprintw(0, 0, curses_version());
    mvprintw(1, 0, "Hello World");
    mvaddch(2, 0, mvinch(1, 4));                 // Why doesn't this work?

    getch();
    endwin();

    return 0;
}

输出:

ncurses 5.9.20130608  
Hello World  

指针在 Helloo 之后闪烁(等待 getch)。

问题:
与在 C 中一样,传递给函数的参数在调用该函数之前首先被评估,mvinch() 将首先被调用,当它 return 字符 o 调用 mvaddch() 将制作。
但是为什么字符 o 没有打印在第 2 行(就在 Hello World 下方)?相反,mvaddch 在当前光标位置打印 o(感谢 winch,即 1,4)。这里 mvaddch() 的行为就像 addch 一样,不考虑 mv 前缀和赋予它的显式移动坐标。为什么?

这可能是 mvaddch() 中的错误还是我遗漏了什么?

编辑:
$ uname -a
Linux Titanic 3.11.0-26-generic #45-Ubuntu SMP Tue Jul 15 04:02:06 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

问题是 mvaddchmvinch 都移动了相同的光标位置,mvinch 稍后计算。

结果是 "o" 被添加回读取它的单元格中,并且没有可见的变化。

mvaddchmvinch 通常都是宏。您可以通过#undef'ing 或将宏名称放在括号中来更改它,例如,

(mvaddch)(2, 0, (mvinch)(1, 4));

因为move是在函数外求值的,求值顺序由宏决定。

问题是mvaddch()恰好是作为宏实现的。像

这样的电话
mvaddch(2, 0, foo);

扩展为以下内容(删除了一些括号):

wmove(stdscr, 2, 0) == -1 ? -1 : waddch(stdscr, foo);

您可以使用例如gcc -E.

如上所示,foo 将在 wmove() 之后计算,这意味着 foo 设置的任何光标位置将优先。

要解决此问题,您可以将 mvinch() 的结果显式保存到 chtype 变量,并在调用 mvaddch().

时使用它

(mvinch() 似乎也是一个宏,根据 wmove()winch() 实现。)