C/C++ comments (annotated)

參考 https://en.cppreference.com/w/c/comment整理一些注意的重點

All comments are removed from the program at translation phase 3 by replacing each comment with a single whitespace character.

這裡描述在translation phase3對於comment做的事,用一個space character取代

translation phase 3可參考C99 §5.1.1.2 (p.10)

3. The source file is decomposed into preprocessing tokens6) and sequences of white-space characters (including comments). A source file shall not end in a partial preprocessing token or in a partial comment. Each comment is replaced by one space character. New-line characters are retained. Whether each nonempty sequence of white-space characters other than new-line is retained or replaced by one space character is implementation-defined

Except within a character constant, a string literal, or a comment, the characters /* introduce a comment.
這邊解釋為什麼 嵌套 /* /* */ */ 會不對稱的原因,因為第二個 /* 已經在 comment內,所以第一個/* 會 match 倒數第二個*/,而留下最後一個不對稱的 */

關於為什麼語言設計時不設計成支援嵌套的原因可參考,http://www.open-std.org/jtc1/sc22/wg14/www/C99RationaleV5.10.pdf 6.4.9

主要的原因是C89的committee認為有其他方式可以處理nested comment,也可參考 comment tips這邊的說明

像上面這種註釋法採用conditional directive有時也被稱為conditioned out,要注意的是 c comment /* */ 的取代還有preprocessing token解析等是在執行preprocessor前進行,所以這邊的#if 0, #endif 的內容一開始也會被處理。

其他有關comment的基本常識
http://www.jargon.net/jargonfile/w/wingedcomments.html
winged comments: 單行 /* */ 註解,相對於boxed comments

/*************************************************
 *
 * This is a boxed comment in C style
 *
 *************************************************/
Posted in C Language | Leave a comment

freestanding program

https://en.cppreference.com/w/c/language/basic_concepts 裡提到
A C program is a sequence of text files (typically header and source files) that contain declarations. They undergo translation to become an executable program, which is executed when the OS calls its main function (unless it is itself the OS or another freestanding program, in which case the entry point is implementation-defined).

freestanding program或是stand-alone program,本身的程式不依靠外部的模組, 通常用在bootstrap loading,因為不依靠外部模組,loader很簡單就直接指到要執行的指令開始跑

在C99規範中,§5.1.2定義了執行環境Execution environments – freestanding、 hosted environment

其中有個重點:
All objects with static storage duration shall be initialized (set to their
initial values) before program startup

Freestanding定義在C99 §5.1.2.1

§5.1.2.1 Freestanding environment In a freestanding environment (in which C program execution may take place without any benefit of an operating system), the name and type of the function called at program startup are implementation-defined. Any library facilities available to a freestanding program, other than the minimal set required by clause 4, are implementation-defined.

描述例如program startup的entry point是implementation defined,相對於我們一般熟知的main(定義在hosted environment §5.1.2.2.1裡)

Posted in C Language | Leave a comment

vim

在vim預設會在檔案尾加上
例如

用hexdump工具看 hexdump -C

代表的是該行結束,接下來的內容會出現在新的一行。
在檔尾的EOL在使用unix工具filter時很重要,
像是多個檔案cat 如果沒有完整行,則下一個檔案的內容會直接接上來

或是計算字數行數的wc: 只會計算完整行 如下面的範例

但有時候可能因為某些原因編輯時需要刻意不加上檔案尾的
要關掉可以下 :set noendofline binary
注意: 只有noendofline還不夠,需要設定成binary

參考:
https://stackoverflow.com/questions/16222530/why-do-i-need-vim-in-binary-mode-for-noeol-to-work

Posted in Tips | Leave a comment

js multiline string的幾種做法

var str1 = "\
  function add1(a,b){\
    return a+b;\
  }\
  console.log(add1(1,2));\
";

var str2 = [
  'function add2(a,b){',
  '  return a+b;',
  '}',
  'console.log(add2(1,2));'
].join('\n');

var str3 = 'function add3(a,b){' +
           '  return a+b;'+
           '}'+
           'console.log(add3(1,2));';

var str4 = ` //ES6
  function add4(a,b){
    return a+b;
  }
  console.log(add4(1,2));
`;

eval(str1);
eval(str2);
eval(str3);
eval(str4);
Posted in nodejs | Leave a comment

chromium with h265 build download

https://chromium.woolyss.com [all codecs]

video test page: https://tools.woolyss.com/html5-audio-video-tester/

Posted in System Administration | Leave a comment

python3 pip upgrade

執行 pip3 install –upgrade pip 更新後出現以下錯誤

修改/usr/bin/pip3即可
參考 https://stackoverflow.com/questions/28210269/importerror-cannot-import-name-main-when-running-pip-version-command-in-windo

Posted in System Administration | Leave a comment

big endian&little endian

在機器層級的指令集裡有些特定的data type,如int, float
以integer bit representation為例,可分為LSB(least significant bit 代表2^0)和MSB(most significant bit 代表 2^(n-1))

我們一般書寫二進位的描述,MSB在左邊,LSB在右邊。
例如書寫一千二百三十四會先寫 1再寫234 (positional notation),就是big endian(從big end開始)寫法,這在一般程式語言裡numeric literal也是這樣表示。

在記憶體中是以多個byte儲存,就會有哪個byte在低位哪個byte在高位
如果方向從MSB開始以byte為單位依序存進記憶體,就是big end=> big endian,
如果方向從LSB開始以byte為單位依序存進記憶體,就是little end=> little endian, 而在記憶體中資料儲存依序的順序是從低位(低位址)開始算。

big endian也叫做network byte order,其實應該是network byte order採用big endian(rfc 1700), 例如ip header裡的total length欄位是跨byte。

對應network byte order是host byte order,這個就要看host本身是big/little endian

ps. MSB: most significant bit, significant中文翻成最高有效位。也可以想成最重要的位元(最大值), 例如平常我們說 1234,一千就是最重要的位(10進位),代表這個數字是1千多。相反地,4是最小的位(10進位),是這個數字最不重要的位,對這個數字大小的影響最小。

以下是用程式判斷big endian or little endian

little endian的系統有個特色,可以直接type punning而不影響值

Posted in General | Leave a comment

javascript code hot swapping

最近看到erlang的動態更新patch
https://stackoverflow.com/questions/1840717/achieving-code-swapping-in-erlangs-gen-server

事實上在nodejs也可以做到類似的作法
基本的思路是透過eval動態將輸入的程式碼字串置換

注意在eval裡面要返回expression value,在裡面的程式碼加上'()’
上面的作法只是一個簡單的範例,
完整的設計可以考慮針對執行介面設計一個code置換處理的handler,
包含如何定位到要改動的變數(狀態)或是函式,透過外部統一的訊息介面將要更新的程式碼送到對應的handler來處理。

這邊主要說明的是當function被置換時,並不會影響到原來正在執行的function,
在javascript裡,function是first-class citizenship,而其生命週期就如同物件的生命週期,但有可能因為javascript engine的optimization而延長。

Posted in nodejs | Leave a comment

define/global define

在上面這段code,裡面使用了boost spirit unicode char_class,在預設情況下,如果沒有#define BOOST_SPIRIT_UNICODE 是compile不過的

如果發現在include前面無論如何define都還是找不到定義的話(qi::unicode),要先檢查是否在include前已經有其他include,導致在一開始include因為還未define而沒有include unicode。

這個比較常發生在cpp include B前又include其他header A,在include A裡已經也include B 就會導致這個現象,這時候除了注意include順序問題,也可以透過compile flag設定global define來解決(g++: -D , -D如果沒指定define值時,預設為1)

Posted in Library | Leave a comment

ssh auto login setup

下載puttygen
https://www.puttygen.com/download-putty

產生出來的public key

---- BEGIN SSH2 PUBLIC KEY ----
Comment: "rsa-key-20190610"
AAAAB3NzaC1yc2EAAAABJQAAAQEAtOBTilvMlexU6mhYroLhSmWIkg/Y3PprVaGO
r7tm7PrScWFGOLUa4hzGTTx1tFl4CnP0rhiJ7cbvhBD6iNfFO2z7GxqMo2nhIOvF
0kejkuKWWsr4yCy9U0NDDLQedYemQvS4XIlULW5h1bLFaOgp+L1FzR75Pn4uFASU
rB/4tfMY9v4adkUwMx2829aSwcrRRKt0caQQLHjjjDoFSiZlHy3jNIy6Kakz6aZb
9Xnmt7r78nvUxhjACm4p/MKuWJOFbDqPTATN8eDsztRsADKFXAvG3dMJowh2hiFi
p4jf78S1VwfOF4//PRovV5SygPeWTzD1hKZ5pWWsgJwt3rYQDQ==
---- END SSH2 PUBLIC KEY ----

將上面那串更新到 ~/.ssh/authorized_keys 注意只有base64的部分並且要是一整行不能斷行

注意 selinux的設定和 authorized_keys 需要是chmod 600
格式為 options, keytype(ssh-rsa), base64-encoded key(AAAAB3N…), comment (options是可選)
可參考 https://en.wikibooks.org/wiki/OpenSSH/Client_Configuration_Files#~/.ssh/authorized_keys

Posted in System Administration | Leave a comment