c-为什么init_pair在COLOR_PAIRS范围的一半范围内失败



在我的平台上:

  • OSX Mojave 10.14.2
  • 来自Homebrew的ncurses:

    $ brew info ncurses
    ncurses: stable 6.1 (bottled) [keg-only]
    

通过这个makefile配置构建:

pkgenv=PKG_CONFIG_PATH=/usr/local/opt/ncurses/lib/pkgconfig pkg-config ncursesw
flags=-Wall -std=c17 -ggdb
cflags=$(flags) $(shell $(pkgenv) --cflags)
ldflags=$(flags) $(shell $(pkgenv) --libs)

这个可重复性最小的例子失败了:

#include <assert.h>
#include <ncursesw/ncurses.h>
int main() {
assert(NULL != initscr());
assert(has_colors());
assert(can_change_color());
assert(ERR != start_color());
assert(COLOR_PAIRS == 0x10000);
assert(COLORS == 256);
assert(ERR != init_pair(1, 9, 10));
assert(ERR != init_pair(0x7FFE, 9, 10));
// OK up to here
// Fails
assert(ERR != init_pair(0x7FFF, 9, 10));
endwin();
puts("OK");
return 0;
}

但为什么呢?COLOR_PAIRS报告的内容(65536)和init_pair接受的内容(1-32766)似乎是两回事。值得一提的是,浏览头文件,

#define NCURSES_PAIRS_T short

奇怪的是,他们选择了一个签名的数量。

颜色对的标准类型是(带符号)short,在大多数机器上是16位。原因是它可以追溯到20世纪80年代,当时空间(和颜色可用性)更加有限。

ncurses 6.1具有允许32位值的扩展(例如,使用init_extended_pair),brew的公式似乎允许这一点,尽管到目前为止还没有人对此发表评论。

init_pair手册页面的便携性部分所述

X/Open Curses 未指定颜色数量限制终端可以支持的颜色对。然而,在使用short对于参数,它继承了SVr4的实现细节编译后的terminfo数据库,该数据库使用有符号的16位数字。这实现提供了这些函数的扩展版本短参数,允许应用程序使用较大的颜色和配对-数字。

为了好玩,这里的屏幕截图使用了ncurses 6.1 的扩展数字功能

最新更新