找回密码
 注册
搜索
系统gho:最纯净好用系统下载站投放广告、加入VIP会员,请联系 微信:wuyouceo
楼主: 不点

cish 开发构想

   火.. [复制链接]
 楼主| 发表于 2018-3-10 20:16:33 | 显示全部楼层
不知 发表于 2018-3-10 18:01
报告一个错误:
printf()打印数字的问题。


这是已知的问题。cling 可能缓存了一行,直到碰上回车符才输出一行(也可能是 printf 自己缓存的,这我不懂)。我改动的部分,不涉及到这个问题。

我不太清楚,是否在调用 refresh 或者 fflush 之类的函数之后,会有不同的结果。你可以在百度搜搜看。

点评

确实需要flush。不过直接编写程序是不需要的。 —————————————————————————————————— cish: [attachimg]368173[/attachimg] _______________________________________________  详情 回复 发表于 2018-3-11 10:20
回复

使用道具 举报

发表于 2018-3-10 22:01:44 | 显示全部楼层
刚才用公众号登录去瞧了下。嗯,网页登录tty,确实很方便使用。

看到最初的提示,提点小意见:
User logged:5
Notice:
1.To use cish,please type cish,you can also add parametors.To view the cish sources,please type cd $src
2.To clean the information on the screen,please type clear.
标点符号后带点空格吧,这样相邻句看起来自然点,要不然给人感觉挤挤的。

试了两个shell命令,ls cd  竟然第二个命令的输出氏一大堆0x
#0 0x000055a7d6e3b8fa llvm::sys::PrintStackTrace(llvm::raw_ostream&) (/home/user/inst/bin/cling+0xaa78fa)
#1 0x000055a7d6e39786 llvm::sys::RunSignalHandlers() (/home/user/inst/bin/cling+0xaa5786)
#2 0x000055a7d6e398cc SignalHandler(int) (/home/user/inst/bin/cling+0xaa58cc)
#3 0x00007fc56ae15140 (/lib/x86_64-linux-gnu/libc.so.6+0x37140)
#4 0x000055a7d6de9c24 shellInterpreter(char const*) (/home/user/inst/bin/cling+0xa55c24)
#5 0x000055a7d6dea9de cling::MetaProcessor::process(llvm::StringRef, cling::Interpreter::CompilationResult&,
cling::Value*, bool) (/home/user/inst/bin/cling+0xa569de)
#6 0x000055a7d6e664cb cling::UserInterface::runInteractively(bool) (/home/user/inst/bin/cling+0xad24cb)
#7 0x000055a7d6c99a8b main (/home/user/inst/bin/cling+0x905a8b)
#8 0x00007fc56adff1c1 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x211c1)
#9 0x000055a7d6d0cc3a _start (/home/user/inst/bin/cling+0x978c3a)
Stack dump:
0.      Program arguments: /home/user/inst/bin/cling
Segmentation fault (core dumped)

public@ttyd:~$

照bash的命令反馈,若cish不氏目录,应该直接告知用户 cish 不氏目录就行了。不能搞出一大堆0x出来。

点评

bug 已修复,请检查。  详情 回复 发表于 2018-3-10 22:48
cd 命令有 bug,会尽快修复。  详情 回复 发表于 2018-3-10 22:12
回复

使用道具 举报

 楼主| 发表于 2018-3-10 22:12:37 | 显示全部楼层
gnuxwy 发表于 2018-3-10 22:01
刚才用公众号登录去瞧了下。嗯,网页登录tty,确实很方便使用。

看到最初的提示,提点小意见:

cd 命令有 bug,会尽快修复。

回复

使用道具 举报

 楼主| 发表于 2018-3-10 22:48:32 | 显示全部楼层
gnuxwy 发表于 2018-3-10 22:01
刚才用公众号登录去瞧了下。嗯,网页登录tty,确实很方便使用。

看到最初的提示,提点小意见:

bug 已修复,请检查。
回复

使用道具 举报

 楼主| 发表于 2018-3-11 03:22:48 | 显示全部楼层
wintoflash 发表于 2018-3-10 12:37
public帐户密码:cish_public
加了1GB的swap

增加 swap 之后,重新从头编译,经过 4 个小时,顺利完成,没有卡顿。
回复

使用道具 举报

发表于 2018-3-11 10:20:05 | 显示全部楼层
不点 发表于 2018-3-10 20:16
这是已知的问题。cling 可能缓存了一行,直到碰上回车符才输出一行(也可能是 printf 自己缓存的,这我 ...

确实需要flush。不过直接编写程序是不需要的。
——————————————————————————————————
cish:
捕获.JPG
________________________________________________________
gcc:
捕获.JPG

点评

受到你的启发,对于 cout,我也找到了一个办法。 如果先执行一条 cout  详情 回复 发表于 2018-3-11 10:51
回复

使用道具 举报

 楼主| 发表于 2018-3-11 10:51:52 | 显示全部楼层
本帖最后由 不点 于 2018-3-11 23:09 编辑
不知 发表于 2018-3-11 10:20
确实需要flush。不过直接编写程序是不需要的。

受到你的启发,对于 cout,我也找到了一个办法。

如果先执行一条

cout << unitbuf;

那么,后续的 cout 就会即时打印。

如果执行一条

cout << nounitbuf;

那么后续的 cout 就会按行缓存,遇到回车才开始输出一行。

对于 printf,我还没找到对策。【更新】找到了,非常棒:

https://stackoverflow.com/questions/1716296/why-does-printf-not-flush-after-the-call-unless-a-newline-is-in-the-format-strin


The stdout stream is buffered, so will only display what's in the buffer after it reaches a newline (or when it's told to). You have a few options to print immediately:

Print to stderr instead using fprintf:

fprintf(stderr, "I will be printed immediately");

Flush stdout whenever you need it to using fflush:

printf("Buffered, will be flushed");
fflush(stdout); // Will now print everything in the stdout buffer

Edit: From Andy Ross's comment below, you can also disable buffering on stdout by using setbuf:

setbuf(stdout, NULL);

就是说,先执行一条 setbuf(stdout, NULL); 就 OK 了。

【补充】但是当使用了 setbuf(stdout, NULL); 之后,我不知道如何恢复为以前的状态(即,缓冲输出的状态)。所以,我感觉还是

printf(...); fflush(stdout);

的方法比较好。这可以写成一个函数(也可以写成一个宏),让它自动 flush。只要不使用 fflush 函数,就仍然是缓冲输出的状态了。

点评

虽然没法直接恢复,但可以用setvbuf设置缓冲(模式:行缓冲,无缓冲,满缓冲)。 —————————————————————————————————————————— [attachimg]368193[/attachimg]  详情 回复 发表于 2018-3-11 14:52

评分

参与人数 1无忧币 +5 收起 理由
不知 + 5 很给力!

查看全部评分

回复

使用道具 举报

发表于 2018-3-11 14:52:28 | 显示全部楼层
不点 发表于 2018-3-11 10:51
受到你的启发,对于 cout,我也找到了一个办法。

如果先执行一条

虽然没法直接恢复,但可以用setvbuf设置缓冲(模式:行缓冲,无缓冲,满缓冲)。
——————————————————————————————————————————
捕获.JPG

点评

不错,又深入了一步。要是能够 get 出 stdout 原有的 buffer,那该多好啊?  详情 回复 发表于 2018-3-11 16:54
回复

使用道具 举报

 楼主| 发表于 2018-3-11 16:54:15 | 显示全部楼层
不知 发表于 2018-3-11 14:52
虽然没法直接恢复,但可以用setvbuf设置缓冲(模式:行缓冲,无缓冲,满缓冲)。
—————————— ...

不错,又深入了一步。要是能够 get  出 stdout 原有的 buffer,那该多好啊?
回复

使用道具 举报

发表于 2018-3-11 17:52:51 | 显示全部楼层
嗯,用公众号登进去又测试了下,这样试了更多的命令,看起来还不错。各反馈如下:
看不合法的提示,应当氏 管道符 和 重定向符不支持的啦。不过确实氏个能用的shell了。

[cling]$ mv ttt1.uxt ttt3.uxt
[cling]$ cat ttt* > ttt03.uxt
this ttt3.uxt file
wordexp: Illegal occurrence of newline or one of |, &, ;, <, >, (, ), {, }.
err=2, cmd=cat ttt* > ttt03.uxt
input_line_12:2:2: error: unknown type name 'cat'
cat ttt* > ttt03.uxt
^
input_line_12:2:9: error: expected ';' at end of declaration
cat ttt* > ttt03.uxt

[cling]$ cat ttt ttt3.uxt > ttt03.uxt
wordexp: Illegal occurrence of newline or one of |, &, ;, <, >, (, ), {, }.
err=2, cmd=cat ttt ttt3.uxt > ttt03.uxt
input_line_13:2:2: error: unknown type name 'cat'
cat ttt ttt3.uxt > ttt03.uxt
^
input_line_13:2:9: error: expected ';' at end of declaration
cat ttt ttt3.uxt > ttt03.uxt
        ^
        ;
[cling]$ vi ttt
[cling]$ vi ttt
[cling]$ vi ttt03.uxt
[cling]$ pwd
/home/public
[cling]$ free
              total        used        free      shared  buff/cache   available
Mem:        1009308      134908       67924       10232      806476      676368
Swap:       1048572      168704      879868
[cling]$ date
Sun Mar 11 09:37:10 UTC 2018
[cling]$ grep "test" ttt
this a test line.

for test cish.
[cling]$ tail ttt03.uxt
this ttt3.uxt file
for test cish de shell cmd.

[cling]$
[cling]$ q
Command not found: q
input_line_14:2:2: error: use of undeclared identifier 'q'
q
^
[cling]$ quit
Command not found: quit
input_line_15:2:2: error: use of undeclared identifier 'quit'
quit
[cling]$ exit
public@ttyd:~$
logout

点评

没错,以下这些内容还没支持: 1、命令以及参数的自动补全。 2、管道 3、输入输出重定向 4、后台执行命令,以及作业控制(job control)等  详情 回复 发表于 2018-3-11 18:08
回复

使用道具 举报

 楼主| 发表于 2018-3-11 18:08:12 | 显示全部楼层
本帖最后由 不点 于 2018-3-12 08:14 编辑
gnuxwy 发表于 2018-3-11 17:52
嗯,用公众号登进去又测试了下,这样试了更多的命令,看起来还不错。各反馈如下:
看不合法的提示,应当氏 ...


没错,以下这些内容还没支持:

1、命令以及参数的自动补全。
2、管道
3、输入输出重定向
4、信号处理
5、后台执行命令,以及作业控制(job control)等

回复

使用道具 举报

发表于 2018-3-11 22:53:04 来自手机 | 显示全部楼层
看不懂,纯掺和。
回复

使用道具 举报

发表于 2018-3-12 20:30:49 | 显示全部楼层
不用急,大师慢慢完善cish就行。。。以后更成熟了,就可以成为cling一个有趣的分支版。

点评

是的,急不来的。时间越久,就越能锤炼出好东西。每个人在不同的时期,会有不同的思路。随着时间的推移,每个人都在进步,外界环境也在变化,说不定当初以为很难做的事情,到那时,水到渠成,不难了。  详情 回复 发表于 2018-3-13 04:15
回复

使用道具 举报

 楼主| 发表于 2018-3-13 04:15:48 | 显示全部楼层
本帖最后由 不点 于 2018-3-13 16:07 编辑
gnuxwy 发表于 2018-3-12 20:30
不用急,大师慢慢完善cish就行。。。以后更成熟了,就可以成为cling一个有趣的分支版。


是的,急不来的。时间越久,就越能锤炼出好东西。每个人在不同的时期,会有不同的思路。随着时间的推移,每个人都在进步,外界环境也在变化,说不定当初以为很难做的事情,到那时,水到渠成,不难了。

一方面要能沉得住气,等到技术成熟再下手,不要匆忙。另一方面,对于感兴趣的各位大人来说,一旦在某方面已经考虑成熟,拖延不是一个选项,该出手时就出手。这软件不是我的,而是大家的。大家共同开发,进步才会快。该出手时不出手,让时光白白流逝,将来会后悔的。

回复

使用道具 举报

 楼主| 发表于 2018-3-13 05:59:59 | 显示全部楼层
记录一下,Windows 下的 rcp 是无用的(把我折腾得够呛),根本与 Linux 不兼容。最后终于找到了 pscp 这个工具,可以在 Windows 和 Linux 之间传输文件,其功能相当于 linux 的 rcp 命令,用法也与 linux 的 rcp 相同(或类似)。

https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html

上面是 putty 的官方下载页,只需下载 pscp 即可,无需下载 putty。

回复

使用道具 举报

 楼主| 发表于 2018-3-13 11:15:01 | 显示全部楼层
记录一下(方便以后找到这个资料),目前在学习《Shell Command Language》
http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html

评分

参与人数 1无忧币 +5 收起 理由
wuyou + 5 不错,我也收藏一下这个链接

查看全部评分

回复

使用道具 举报

 楼主| 发表于 2018-3-13 13:23:14 | 显示全部楼层
今天又改动了一点点。以数字( 0~9 )或左括号( “(” ) 开头的行,都作为 C 代码来处理。这样方便用 C 语言的功能来在命令行下进行计算。shell 本身也能计算,但是需要像这样

expr  3 + 5
expr  2 \* 7
echo  $(( 5 * 9 ))

比较累赘。而用 cish 的命令行,直接敲入 5*7 回车,得到 (int) 35,这就快捷多了。
回复

使用道具 举报

 楼主| 发表于 2018-3-13 17:42:20 | 显示全部楼层
在 shell 规范中,shell 也有函数。我在考虑,最好是能把 shell 的函数与 C 的函数进行某种整合,统一处理。
回复

使用道具 举报

发表于 2018-3-14 22:44:41 | 显示全部楼层
嗯,老大应该在本贴的首楼中,直接贴上网址,公用帐号,密码,方便有兴趣的坛友点进来就能进去瞧瞧。

屮目前编程水平未入门,最近几年如果有时间,也会专注于弄个自已能用的输入法,毕竟一直没有自已用
得爽的输服台,心里总氏不舒服,不管时间多长,反正有生之年一定要搞定它。等搞定这个问题之后,如果
水平提高了,或许会参与其他的开源项目。

目前嘛,只能氏闲逛其他gnux网站,论坛,贴吧时顺便帮老大宣传一下啦。。。

回复

使用道具 举报

 楼主| 发表于 2018-3-15 08:41:34 | 显示全部楼层
今天了解了 cling 的输出重定向。为了让 cling 不显示出错信息,找了很久,都没找到办法。用重定向的方法,算是权宜之计。

输入
  1. .2> /dev/null
复制代码


后续的出错信息都看不见了。

再输入
  1. .2>
复制代码


(文件名的位置是空的,即,不填文件名,其作用是撤销前面的重定向),则后续的出错信息就又能显示出来了。
回复

使用道具 举报

 楼主| 发表于 2018-3-16 10:28:33 | 显示全部楼层
本帖最后由 不点 于 2018-3-20 15:26 编辑

正如以前所说的,整合就需要权衡。经过一段时间的实践和认识,现在我又回到 “以 C 为重心” 的思路上了。

昨天找到了屏蔽 Cling 出错信息的办法。这不彻底。彻底的办法应该是把出错信息保存起来,当需要的时候,让它显现;当不需要的时候,让它隐藏。但出错信息不可以保存在磁盘文件上(影响执行效率,也影响磁盘寿命),应该保存在内存中。

如果找到这样的办法,就可以首先用 C 解释,当出现语法错误时,再按 shell 命令来解释。

当涉及到 “编程” 这个话题的时候,还得依靠 C,不能依靠 shell。

shell 主要只是用来运行命令罢了。




为什么要先用 C 解释呢?因为处理逻辑简单。C 解释时,出现语法错误的,都可以当作 Shell 来解释,不啰嗦。如果先用 shell 解释,为了不把 C 代码当成 shell 来解释,就需要用排除法,排除很多具有 C 特征的行,而且尽管排除了很多,也难以全面彻底地排除。




当敲入 ls 之类的 shell 命令时,由于 Cling 把它当成 C 语言代码来处理,因此 Cling 会报错。要想屏蔽出错信息,可以注释掉

src/tools/clang/lib/Sema/SemaExpr.cpp

中如下一行(这是通过艰苦调试发现的!)

  Diag(R.getNameLoc(), diagnostic) << Name;

但若想把出错信息保存在某个字符串中,则相当不容易,因为 C++ 比 C 复杂得多,光是找 Diag () 的定义,我都搞不定。【后来通过把 cerr 重定向到 stringstream 中巧妙解决了这个问题。】

点评

有个tinycc,很小的C语言编译解释器,你把解析的部分拿出来, 先用解析器跑下输入的代码,能过就当C,不能就当shell。 你通过个别字符的方式,简单语句还行,复杂些会出问题。 玩耍到研究方向的话, 引入神经  详情 回复 发表于 2018-3-16 19:30
回复

使用道具 举报

发表于 2018-3-16 19:30:53 | 显示全部楼层
不点 发表于 2018-3-16 10:28
正如以前所说的,整合就需要权衡。经过一段时间的实践和认识,现在我又回到 “以 C 为重心” 的思路上了。
...

有个tinycc,很小的C语言编译解释器,你把解析的部分拿出来,
先用解析器跑下输入的代码,能过就当C,不能就当shell。
你通过个别字符的方式,简单语句还行,复杂些会出问题。

玩耍到研究方向的话,
引入神经网络,给他shell和C的代码训练识别度,
很快就可以到一个满意的识别度,不过编程语言这种特别规范的,不太需要,
还是标准解析过一遍实在。

点评

不错的思路。我其实挺喜欢小的东西。假如 cling 啃不动的话,可能我就会采用 tinycc 之类的小工具了。 希望有人去做 tinycc 的工作。  详情 回复 发表于 2018-3-16 23:23
回复

使用道具 举报

 楼主| 发表于 2018-3-16 23:23:33 | 显示全部楼层
slore 发表于 2018-3-16 19:30
有个tinycc,很小的C语言编译解释器,你把解析的部分拿出来,
先用解析器跑下输入的代码,能过就当C,不 ...

不错的思路。我其实挺喜欢小的东西。假如 cling 啃不动的话,可能我就会采用 tinycc 之类的小工具了。

希望有人去做 tinycc 的工作。
回复

使用道具 举报

 楼主| 发表于 2018-3-18 04:57:13 | 显示全部楼层
本帖最后由 不点 于 2018-3-20 15:59 编辑

现在已经调整为优先用 C 解释。当用 C 解释失败时,再用 shell 命令来解释。

在命令行敲入 M_PIM_PIl
(右边是小写的 L 表示双精度,不是数字 1回车,可打印出圆周率 π 的值。
在命令行敲入 M_EM_El (右边是小写的 L 表示双精度,不是数字 1)回车,可打印出自然对数的底 e 的值。

以上常数是在 math.h 中定义的,可以用来进行数值计算。优先用 C 解释的好处是,宏定义以及全局常量、全局变量、全局函数,都能直接使用。

敲入 chdir obj 回车,会进入 obj 子目录中。以下是处理过程:


  1. [cling]% chdir obj
  2. input_line_15:2:7: error: expected ';' after expression
  3. chdir obj                  由于先用 C 解释,所以会报错。
  4.       ^
  5.       ;
  6. input_line_15:2:8: error: use of undeclared identifier 'obj'
  7. chdir obj
  8.        ^
  9. input_line_16:2:8: error: use of undeclared identifier 'obj'
  10. chdir(obj)  失败后,进行第 2 次尝试,这次加上括号。但仍然失败。
  11.        ^
  12. (int) 0  最后为什么成功了呢?因为进行了第三次尝试:为参数加上了引号 chdir("obj") 当然就成功了。注意 chdir 是 C 的库函数(或者是系统调用)。下面的 pwd 命令能够验证确实进入 obj 子目录了。
  13. [cling]% pwd
  14. input_line_19:2:2: error: use of undeclared identifier 'pwd'
  15. pwd                同样地,先用 C 解释 pwd 是失败的。
  16. ^
  17. input_line_20:2:2: error: use of undeclared identifier 'pwd'
  18. pwd()              自动加上括号,当作函数调用,再试一次。但仍然失败。
  19. ^
  20. input_line_21:2:2: error: use of undeclared identifier 'pwd'
  21. pwd(0)         第三次尝试,加上参数 0。仍然失败。
  22. ^
  23. input_line_22:2:2: error: use of undeclared identifier 'pwd'
  24. pwd("")        第四次尝试,参数换成空字符串。仍然失败。
  25. ^
  26. /home/user/obj  最后为什么成功了呢?因为是交给 shell 模块执行了。这条信息是外部命令 pwd 打印出来的。
  27. [cling]%
复制代码
回复

使用道具 举报

 楼主| 发表于 2018-3-18 05:10:25 | 显示全部楼层
再举一例,用 cd obj 来进入 obj 目录:

  1. [cling]$ cd obj
  2. input_line_11:2:2: error: unknown type name 'cd'
  3. cd obj              先用 C 来解释,当然是失败的。
  4. ^
  5. input_line_12:2:5: error: use of undeclared identifier 'obj'
  6. cd(obj)       自动加上括号,进行第二次尝试,结果仍然失败。
  7.     ^
  8. input_line_13:2:2: error: use of undeclared identifier 'cd'
  9. cd("obj")     自动加上引号,进行第三次尝试,结果仍然失败(因为不存在 cd 这个函数)。
  10. ^
  11. 然而,下面的 pwd 命令却证实,cd obj 执行成功了。为什么呢?因为自动进行了第四次尝试,即 交给 shell 处理模块来执行。由于 shell 模块当中有个内部命令叫做 cd,所以就执行成功了。
  12. [cling]% pwd
  13. input_line_14:2:2: error: use of undeclared identifier 'pwd'
  14. pwd
  15. ^
  16. input_line_15:2:2: error: use of undeclared identifier 'pwd'
  17. pwd()
  18. ^
  19. input_line_16:2:2: error: use of undeclared identifier 'pwd'
  20. pwd(0)
  21. ^
  22. input_line_17:2:2: error: use of undeclared identifier 'pwd'
  23. pwd("")
  24. ^
  25. /home/user/obj
  26. [cling]%
复制代码
回复

使用道具 举报

 楼主| 发表于 2018-3-18 05:28:14 | 显示全部楼层
再举一例,用 exit 退出 cish 环境:

  1. [cling]% exit
  2. (void (*)(int) __attribute__((noreturn)) throw()) Function @0x7f7d38e25f00
  3. 看到没有?先用 C 解释,就成功了!因为 exit 确实是个系统调用,是个已经定义了的函数,它的地址被打印出来了。

  4. 由于已经发现它是函数,因此,进行第二次计算,这次加上括号:

  5. input_line_20:2:2: error: no matching function for call to 'exit'
  6. exit()      但不幸的是,失败了,因为 exit 要求有一个参数。
  7. ^~~~
  8. /usr/include/stdlib.h:499:13: note: candidate function not viable: requires single argument '__status', but no arguments were provided
  9. extern void exit (int __status) __THROW __attribute__ ((__noreturn__));
  10.             ^
  11. user@ttyd:~$ 然而,看到没有?shell 提示符显示出来了!这说明已经成功退出 cish 了!为什么呢?因为自动进行了第三次尝试,加上参数 0,变成这样:exit(0) ——这当然能执行成功了,因为它是合法的 C 语句。这个语句执行完毕,当然就退出 cish 而回到 bash 的提示符了。
复制代码
回复

使用道具 举报

 楼主| 发表于 2018-3-18 05:52:46 | 显示全部楼层
刚才只用 C 语言的 exit 函数,就退出了。那么,我们先前写好的 shell 内部命令 exit 就没有机会获得执行了。下面用 “歪门邪道”来执行内部命令 exit,即,在 exit 后面添加一个参数 #,即,非法参数。碰巧我们的内部命令能够容忍这个非法参数,因此,可以成功执行。


  1. [cling]$ exit #
  2. input_line_11:2:6: error: expected ';' after expression
  3. exit #           先用 C 解释,当然会失败。
  4.      ^
  5.      ;
  6. input_line_11:2:7: error: expected expression
  7. exit #
  8.       ^
  9. input_line_12:2:7: error: expected expression
  10. exit(#)          自动进行第二次尝试,加上括号,仍然失败。
  11.       ^
  12. input_line_13:2:2: error: no matching function for call to 'exit'
  13. exit("#")     自动进行第三次尝试,为参数加上引号,仍旧失败。
  14. ^~~~
  15. /usr/include/stdlib.h:499:13: note: candidate function not viable: no known conversion from 'const char [2]' to 'int' for 1st argument
  16. extern void exit (int __status) __THROW __attribute__ ((__noreturn__));
  17.             ^
  18. user@ttyd:~$
复制代码

看到 bash 提示符,知道是成功了。为什么能成功呢?因为自动进行了第四次尝试,交给 shell 模块来执行了。我们先前写的那个 shell 内部命令 exit 可以接受一个非法参数。这样就成功退回到 bash 了。
回复

使用道具 举报

 楼主| 发表于 2018-3-18 12:02:26 | 显示全部楼层
本帖最后由 不点 于 2018-3-18 14:11 编辑

发现 Cling 的一个 bug:除以零时崩溃(core dumped)。

1/0 会正常报错,0/0 也会正常报错。这是因为编译器在编译阶段都能够发现分母为零,所以能够报错,不至于崩溃。

然而,

int k=0
0/k

这就崩溃了。说明 Cling 在运行时有 bug。

如果改成
0.0/k
1.0/k
1/(k+0.0)
都不会崩溃。这说明浮点计算很健壮,而整数计算不太完善。




----更新----

证明是 C 库函数有 bug,不是 Cling 的责任。

以下是 test.c 的内容,用 gcc test.c 或 g++ test.c 来编译,执行 ./a.out 它能成功打印出 OK!

但是,如果把浮点数 0.0 变成整数 0,则不能打印出 OK,而是显示 “浮点数异常”,程序崩溃了。

另外,崩溃时,它显示的信息也不准确。不应该显示 “浮点数异常”,而应该显示 “整数除以零错误”,或 “整数除法异常”。

这证明了问题的根源是库函数。



  1. #include <stdio.h>

  2. int
  3. main ()
  4. {
  5.         int k=0;

  6.         k = (k+0.0) / k;

  7.         printf ("OK!\n");
  8.         return 0;
  9. }
复制代码


回复

使用道具 举报

发表于 2018-3-18 23:11:14 | 显示全部楼层
噢,又来瞧大师的工作了。。。很有趣。。。嗯,还氏先进行C解释,发现行不通再改为shell执行。

另,楼上大师说的那个除零问题报错,很可能的原因氏数据类型转换有关。
因为编译发x.y这样的形式,估计氏当作浮点数对待的。有可能0.0实际上变成了最小的浮点常量。

这样浮数和整数一齐做加法运算时,统统转为浮点。最后做除法,结果就报浮点出错啦。。。
回复

使用道具 举报

 楼主| 发表于 2018-3-19 23:12:18 | 显示全部楼层
本帖最后由 不点 于 2018-3-20 13:51 编辑

记录一下。搜 “redirect stderr to stream c++” 找到:
https://stackoverflow.com/questions/5419356/redirect-stdout-stderr-to-a-string/24796475




庆祝一下。上述网页真棒!搞定了!把出错信息重定向到 stringstream 中,竟然如此简单!

cish 又上新台阶,这次真正调整过来了,即先按 C 解释,最后用 shell 解释。如果 shell 命令执行成功,则不显示出错信息。如果 shell 命令执行失败,则先显示 shell 出错信息,再显示 C 语言出错信息。

不过,目前在复合语句(if,switch,for,while 等结构)中暂不支持 shell 命令。目前只在 “简单语句(单行语句)” 的情况下才可以使用 shell 命令。



回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|捐助支持|无忧启动 ( 闽ICP备05002490号-1|闽公网安备35020302032614号 )

GMT+8, 2026-7-22 05:55

Powered by Discuz! X5.0

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表