后记:`cvs` 是否终止字符串缓冲区?

PostScript: Does `cvs` terminate the string buffer?

使用 cvs 的一个想法是通过重新使用字符串缓冲区来帮助垃圾收集器,例如

/s 5 string def
s 2 cvs %...
s 66 cvs %...

然而,当在循环中做这样的事情时,实际在缓冲区中找到的字符串是:

(-40.0)
(-30.0)
(-20.0)
(-10.0)
(0.0.0)
(10.00)
(20.00)
(30.00)
(40.00)

所以看起来字符串在转换结束时没有终止(在 GhostScript 9.26 中找到)。不幸的是,GhostScript 参考手册对字符串是否会被终止有些沉默。

所以问题是:预期的行为是什么?

当尝试类似 val str dup 2 0 put cvs 的结果时(如 == 所示):

(-40.0)
(-30.0)
(-20.0)
(-10.0)
(0.0[=12=]00)
(10.00)
(20.00)
(30.00)
(40.00)

那么重新使用字符串缓冲区到底是不是一个坏主意?

更新 1:

我发现放在栈上的值是正确的,而缓冲区中的值不正确:

val s1 cvs pop            % leaves the wrong value in s1
val s1 cvs /s2 exch def   % leaves the correct value in s2

后记字符串不是 C 字符串。特别是,它们不是以 NUL 结尾的;相反,它们有明确的长度,就像 Postscript 数组一样。字符串(或数组)一旦创建就无法修改其长度,但可以创建子字符串(或子数组)的视图("interval" 在 Postscript 术语中)。间隔不是副本;它与底层字符串(数组)共享存储空间。

cvs 接受一个字符串(用作缓冲区)作为参数,用转换为字符串的值参数覆盖缓冲区的初始段,并且 return将该段作为间隔。 (请参阅 PLRM 第 568 页;我懒得重新输入它。)如果您不想在转换后的值末尾出现垃圾,则可以使用 return 值。 (但是 returned 值只有在您不将底层缓冲区用于其他用途时才有效。)