<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: shajunxing</title>
    <description>The latest articles on DEV Community by shajunxing (@shajunxing).</description>
    <link>https://dev.to/shajunxing</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3118106%2Fb2b9ac1f-370c-42e4-89fa-f3dbb8e757f0.jpeg</url>
      <title>DEV Community: shajunxing</title>
      <link>https://dev.to/shajunxing</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/shajunxing"/>
    <language>en</language>
    <item>
      <title>Banana CVar, a set of advanced data types in C that supports garbage collection</title>
      <dc:creator>shajunxing</dc:creator>
      <pubDate>Mon, 23 Jun 2025 15:45:17 +0000</pubDate>
      <link>https://dev.to/shajunxing/banana-cvar-a-set-of-advanced-data-types-in-c-that-supports-garbage-collection-2ppg</link>
      <guid>https://dev.to/shajunxing/banana-cvar-a-set-of-advanced-data-types-in-c-that-supports-garbage-collection-2ppg</guid>
      <description>&lt;p&gt;This article is openly licensed via &lt;a href="https://creativecommons.org/licenses/by-nc-nd/4.0/" rel="noopener noreferrer"&gt;CC BY-NC-ND 4.0&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Project Address: &lt;a href="https://github.com/shajunxing/banana-cvar" rel="noopener noreferrer"&gt;https://github.com/shajunxing/banana-cvar&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is an example of using data types and garbage collector from project &lt;a href="https://github.com/shajunxing/banana-script" rel="noopener noreferrer"&gt;https://github.com/shajunxing/banana-script&lt;/a&gt; in C program. Rule for garbage collection in C program is quite simple: Record value and address of each variable. If value at address matches recorded value, it's marked as being in use because that means call stack hasn't changed. On the other side, if leave that variable scope, such as when function exits, these two will eventually not match.&lt;/p&gt;

&lt;p&gt;How to build see &lt;a href="https://github.com/shajunxing/banana-script" rel="noopener noreferrer"&gt;https://github.com/shajunxing/banana-script&lt;/a&gt; and will not be repeated.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;example.c&lt;/code&gt;, if you comment out line &lt;code&gt;gc();&lt;/code&gt; and check task manager, you’ll see memory keeps growing. This happens because &lt;code&gt;var f = string("This is a dynamic string");&lt;/code&gt; is dynamically allocating memory. But if you uncomment that line, memory stabilizes and doesn't grow, which shows that garbage collection strategy is really successful.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;"var.h"&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;scripture&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"This is a constant string"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"This is a dynamic string"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(;;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;gc&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;EXIT_SUCCESS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>Banana Script, An inperpreter for a strict subset of JavaScript</title>
      <dc:creator>shajunxing</dc:creator>
      <pubDate>Mon, 23 Jun 2025 15:42:56 +0000</pubDate>
      <link>https://dev.to/shajunxing/-banana-script-an-inperpreter-for-a-strict-subset-of-javascript-5ai9</link>
      <guid>https://dev.to/shajunxing/-banana-script-an-inperpreter-for-a-strict-subset-of-javascript-5ai9</guid>
      <description>&lt;p&gt;This article is openly licensed via &lt;a href="https://creativecommons.org/licenses/by-nc-nd/4.0/" rel="noopener noreferrer"&gt;CC BY-NC-ND 4.0&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Project Address: &lt;a href="https://github.com/shajunxing/banana-script" rel="noopener noreferrer"&gt;https://github.com/shajunxing/banana-script&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;My goal is to remove and modify useless and ambiguous parts of JavaScript language that I've summarized in practice, and to create a minimal syntax interpreter by keeping only what I like and need. &lt;strong&gt;Only JSON-compatible data types and function are supported, function is first-class value, and function supports closure. I don't like object-oriented programming, so everything class related are not supported&lt;/strong&gt;. There are no built-in immunable global variables, global functions, or object members, even contents added during interpreter initialization can be easily deleted at any time and reverted to clean empty state.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two-Minute Brief Syntax Guide for Proficient JavaScript Users
&lt;/h2&gt;

&lt;p&gt;Data types are &lt;code&gt;null&lt;/code&gt; &lt;code&gt;boolean&lt;/code&gt; &lt;code&gt;number&lt;/code&gt; &lt;code&gt;string&lt;/code&gt; &lt;code&gt;array&lt;/code&gt; &lt;code&gt;object&lt;/code&gt; &lt;code&gt;function&lt;/code&gt;, results of &lt;code&gt;typeof&lt;/code&gt; correspond strictly to these names. No &lt;code&gt;undefined&lt;/code&gt; because &lt;code&gt;null&lt;/code&gt; is enough. Array and object are clean, no predefined members such as &lt;code&gt;__proto__&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Variable declaraction use &lt;code&gt;let&lt;/code&gt;, all variables are local, &lt;code&gt;const&lt;/code&gt; is not supported because all must be deletable. Access undeclared variables will cause error, access array/object's unexisting members will get &lt;code&gt;null&lt;/code&gt;, and put &lt;code&gt;null&lt;/code&gt; will delete corresponding member.&lt;/p&gt;

&lt;p&gt;Function definition supports default parameter &lt;code&gt;param = value&lt;/code&gt; and rest parameter &lt;code&gt;...params&lt;/code&gt;. Array literal and function call support spread syntax &lt;code&gt;...&lt;/code&gt;, which will not skip &lt;code&gt;null&lt;/code&gt; members. No predefined members such as &lt;code&gt;this&lt;/code&gt; &lt;code&gt;arguments&lt;/code&gt; in function. If &lt;code&gt;return&lt;/code&gt; is outside function, means exit vm.&lt;/p&gt;

&lt;p&gt;Operators follow strict rule, no implicit conversion. Only boolean can do logical operations. &lt;code&gt;== !=&lt;/code&gt; are strict meaning, and can be done by all types. Strings can do all relational operations and &lt;code&gt;+&lt;/code&gt;. Numbers can do all relational and numerical operations. Operator precedence from low to high is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ternary operator &lt;code&gt;?&lt;/code&gt; &lt;code&gt;:&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Logical or operator &lt;code&gt;||&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Logical and operator &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Relational operator &lt;code&gt;==&lt;/code&gt; &lt;code&gt;!=&lt;/code&gt; &lt;code&gt;&amp;lt;&lt;/code&gt; &lt;code&gt;&amp;lt;=&lt;/code&gt; &lt;code&gt;&amp;gt;&lt;/code&gt; &lt;code&gt;&amp;gt;=&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Additive operator &lt;code&gt;+&lt;/code&gt; &lt;code&gt;-&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Multiplicative operator &lt;code&gt;*&lt;/code&gt; &lt;code&gt;/&lt;/code&gt; &lt;code&gt;%&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Exponential operator &lt;code&gt;**&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Prefix operator &lt;code&gt;+&lt;/code&gt; &lt;code&gt;-&lt;/code&gt; &lt;code&gt;!&lt;/code&gt; &lt;code&gt;typeof&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Array/object member access and function call operator &lt;code&gt;[]&lt;/code&gt; &lt;code&gt;.&lt;/code&gt; &lt;code&gt;?.&lt;/code&gt; &lt;code&gt;()&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Assignment expression &lt;code&gt;=&lt;/code&gt; &lt;code&gt;+=&lt;/code&gt; &lt;code&gt;-=&lt;/code&gt; &lt;code&gt;*=&lt;/code&gt; &lt;code&gt;/=&lt;/code&gt; &lt;code&gt;%=&lt;/code&gt; &lt;code&gt;++&lt;/code&gt; &lt;code&gt;--&lt;/code&gt; does not return value, Comma expression &lt;code&gt;,&lt;/code&gt; is not supported.&lt;/p&gt;

&lt;p&gt;Conditional statement is &lt;code&gt;if&lt;/code&gt;, loops are &lt;code&gt;while&lt;/code&gt; &lt;code&gt;do while&lt;/code&gt; &lt;code&gt;for&lt;/code&gt;, conditions must be boolean. &lt;code&gt;for&lt;/code&gt; loop only support following syntax, &lt;code&gt;[]&lt;/code&gt; means optional. &lt;code&gt;for in&lt;/code&gt; and &lt;code&gt;for of&lt;/code&gt; only handle non-null members:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;for ([[let] variable = expression ] ; [condition] ; [assignment expression])&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;for ([let] variable in array/object)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;for ([let] variable of array/object)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No modules. In inperpreter's view, source code is only one large flat text.&lt;/p&gt;

&lt;p&gt;Garbage collection is manual, you can do it at any time you need.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;delete&lt;/code&gt; means delete local variable within current scope (object members can be deleted by setting &lt;code&gt;null&lt;/code&gt;). For example, variables added to the function closure are all local variables before return, so unused variables can be &lt;code&gt;delete&lt;/code&gt;d before return to reduce closure size, run following two statements in REPL environment to see differences.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;let f = function(a, b){let c = a + b; return function(d){return c + d;};}(1, 2); dump(); print(f(3)); delete f;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;let f = function(a, b){let c = a + b; delete a; delete b; return function(d){return c + d;};}(1, 2); dump(); print(f(3)); delete f;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;throw&lt;/code&gt; can throw any value, which are received by &lt;code&gt;catch&lt;/code&gt;. &lt;code&gt;finally&lt;/code&gt; is not supported, because I think it's totally unecessary, and will make code execution order weird.&lt;/p&gt;

&lt;h2&gt;
  
  
  Technical internals
&lt;/h2&gt;

&lt;p&gt;This project is C99 compatable, no other dependences, even make systems are not necessary, only need C compiler, compilation environment is msgc/gcc/mingw. First, from &lt;a href="https://github.com/shajunxing/banana-nomake" rel="noopener noreferrer"&gt;https://github.com/shajunxing/banana-nomake&lt;/a&gt; download single file &lt;code&gt;make.h&lt;/code&gt;, then open &lt;code&gt;make.c&lt;/code&gt;, modify &lt;code&gt;#include&lt;/code&gt; to correct path, then with msvc type &lt;code&gt;cl make.c &amp;amp;&amp;amp; make.exe release&lt;/code&gt;, or with mingw type &lt;code&gt;gcc -o make.exe make.c &amp;amp;&amp;amp; ./make.exe release&lt;/code&gt;. Executables are in &lt;code&gt;bin&lt;/code&gt; folder.&lt;/p&gt;

&lt;p&gt;Project follows "minimal dependency" rule, only including necessary headers. Also, there's only one-way referencing between modules, with no circular referencing. Here’s how modules work and their dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    js-common   js-data     js-vm       js-syntax
        &amp;lt;-----------
                    &amp;lt;-----------
                                &amp;lt;-----------
        &amp;lt;-----------------------
        &amp;lt;-----------------------------------
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;js-common&lt;/code&gt;: Constants, macro definitions, and functions common to project, such as log, memory io&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;js-data&lt;/code&gt;: Data types and garbage collection, you can even use this module separately in C projects to manipulate high-level data structures with GC functionality, see &lt;a href="https://github.com/shajunxing/banana-cvar" rel="noopener noreferrer"&gt;https://github.com/shajunxing/banana-cvar&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;js-vm&lt;/code&gt;: Bytecode Virtual Machine, compiled separately to get an interpreter with minimal footprint without source code parsing&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;js-syntax&lt;/code&gt;: Lexical parsing and syntax parsing, which converts source code into bytecode&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All values are &lt;code&gt;struct js_value&lt;/code&gt; type, you can create by &lt;code&gt;js_xxx()&lt;/code&gt; functions, &lt;code&gt;xxx&lt;/code&gt; is value type, and you can read c values direct from this struct, see definition in &lt;code&gt;js_data.h&lt;/code&gt;. Created values follow garbage collecting rules. DON'T directly modify their content, if you want to get different values, create new one. Compound types &lt;code&gt;array&lt;/code&gt; &lt;code&gt;object&lt;/code&gt; can be operated by &lt;code&gt;js_array_xxx()&lt;/code&gt; &lt;code&gt;js_object_xxx()&lt;/code&gt; functions.&lt;/p&gt;

&lt;p&gt;C functions must be &lt;code&gt;struct js_result (*)(struct js_vm *)&lt;/code&gt; format, use &lt;code&gt;js_c_function()&lt;/code&gt; to create c function value, yes of course they are all values and can be put anywhere, for example, if put on stack root using &lt;code&gt;js_variable_declare()&lt;/code&gt;, they will be global. &lt;code&gt;struct js_result&lt;/code&gt; has two members, if &lt;code&gt;.success&lt;/code&gt; is true, &lt;code&gt;.value&lt;/code&gt; is return value, if false, &lt;code&gt;.value&lt;/code&gt; is received by &lt;code&gt;catch&lt;/code&gt; if there are &lt;code&gt;try catch&lt;/code&gt;. c function can also call script function using &lt;code&gt;js_call()&lt;/code&gt;. Inside C function, use &lt;code&gt;js_parameter_base()&lt;/code&gt; &lt;code&gt;js_parameter_length()&lt;/code&gt; &lt;code&gt;js_parameter_get()&lt;/code&gt; to get passed in parameters.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Merge malloc/calloc/realloc/free into one safe macro, and test code</title>
      <dc:creator>shajunxing</dc:creator>
      <pubDate>Fri, 13 Jun 2025 02:07:44 +0000</pubDate>
      <link>https://dev.to/shajunxing/merge-malloccallocreallocfree-into-one-safe-macro-and-test-code-1022</link>
      <guid>https://dev.to/shajunxing/merge-malloccallocreallocfree-into-one-safe-macro-and-test-code-1022</guid>
      <description>&lt;p&gt;I standalize actions of checking NULL before allocation, setting pointer to NULL after released, and initializing newly allocated memory to 0. Only flaw is, pointer must be manually initized to NULL on declaraction, which cannot be gracefully implemented by macro.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;string.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;time.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="cp"&gt;#define log_error(__arg_format, ...) \
    printf("ERROR %s:%d:%s: " __arg_format "\n", __FILE__, __LINE__, __func__, ##__VA_ARGS__)
&lt;/span&gt;
&lt;span class="cp"&gt;#define fatal(__arg_format, ...)                                \
    do {                                                        \
        log_error("Fatal error: " __arg_format, ##__VA_ARGS__); \
        abort();                                                \
    } while (0)
&lt;/span&gt;
&lt;span class="cp"&gt;#define enforce(__arg_condition)                               \
    do {                                                       \
        if (!(__arg_condition)) {                              \
            fatal("Enforcement failed: %s", #__arg_condition); \
        }                                                      \
    } while (0)
&lt;/span&gt;
&lt;span class="cp"&gt;#if defined(_WIN32)
&lt;/span&gt;    &lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;malloc.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;    &lt;span class="cp"&gt;#define allocated_size _msize
#elif defined(__linux__)
&lt;/span&gt;    &lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;malloc.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;    &lt;span class="cp"&gt;#define allocated_size malloc_usable_size
#elif defined(__APPLE__)
&lt;/span&gt;    &lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;malloc/malloc.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;    &lt;span class="cp"&gt;#define allocated_size malloc_size
#else
&lt;/span&gt;    &lt;span class="cp"&gt;#error Looking up allocated memory block size is not supported in this platform.
#endif
&lt;/span&gt;
&lt;span class="cp"&gt;#define allocate(__arg_pointer, __arg_unit_count)                                             \
    do {                                                                                      \
        typeof(__arg_unit_count) __unit_count = __arg_unit_count;                             \
        size_t __size_per_unit = sizeof(typeof(*__arg_pointer));                              \
        size_t __size = __unit_count * __size_per_unit;                                       \
        if (__arg_pointer == NULL) {                                                          \
            if (__unit_count &amp;gt; 0) {                                                           \
                __arg_pointer = (typeof(__arg_pointer))calloc(__unit_count, __size_per_unit); \
                enforce(__arg_pointer != NULL);                                               \
            }                                                                                 \
        } else {                                                                              \
            if (__unit_count &amp;gt; 0) {                                                           \
                size_t __old_size = allocated_size(__arg_pointer);                            \
                __arg_pointer = (typeof(__arg_pointer))realloc(__arg_pointer, __size);        \
                enforce(__arg_pointer != NULL);                                               \
                if (__size &amp;gt; __old_size) {                                                    \
                    memset((char *)(__arg_pointer) + __old_size, 0, __size - __old_size);     \
                }                                                                             \
            } else {                                                                          \
                free(__arg_pointer);                                                          \
                __arg_pointer = NULL;                                                         \
            }                                                                                 \
        }                                                                                     \
    } while (0)
&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;foo&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;short&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// msvc compile options: cl /W3 /utf-8 /std:clatest&lt;/span&gt;
&lt;span class="c1"&gt;// open task manager to check whether memory leaks&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;old_count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;new_count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;offset&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;srand&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="kt"&gt;unsigned&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(;;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// check whether old memory is 0xff&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;offset&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;offset&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;old_count&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;offset&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;offset&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="n"&gt;enforce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;enforce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;enforce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;enforce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="c1"&gt;// set a smaller value to make more 0 appear for testing 'free()'&lt;/span&gt;
        &lt;span class="n"&gt;new_count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rand&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;allocate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;new_count&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// check whether new space is 0&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;offset&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;old_count&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;offset&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new_count&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;old_count&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;offset&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;offset&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="n"&gt;enforce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;enforce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;enforce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;enforce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="c1"&gt;// fill 0xff&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;offset&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;offset&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;new_count&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;offset&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;offset&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;old_count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;new_count&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;EXIT_SUCCESS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>Ways for extracting portable version of Microsoft Visual C/C++ compiler</title>
      <dc:creator>shajunxing</dc:creator>
      <pubDate>Tue, 20 May 2025 04:50:35 +0000</pubDate>
      <link>https://dev.to/shajunxing/ways-for-extracting-portable-version-of-microsoft-visual-cc-compiler-51dd</link>
      <guid>https://dev.to/shajunxing/ways-for-extracting-portable-version-of-microsoft-visual-cc-compiler-51dd</guid>
      <description>&lt;p&gt;Although even visual studio build tool must be installed, command line compiler can actually run completely independently, so you can install it in any temporary location (such as in virtual machine), and then use following batch script to extract it, note that directories, version numbers, etc. should be modified according to your actual situation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight batchfile"&gt;&lt;code&gt;@echo &lt;span class="na"&gt;off&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="na"&gt;/d &lt;/span&gt;&lt;span class="vm"&gt;%~dp0&lt;/span&gt;
&lt;span class="nb"&gt;robocopy&lt;/span&gt; &lt;span class="na"&gt;/mir &lt;/span&gt;&lt;span class="s2"&gt;"C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.43.34808\bin\Hostx64\x64"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;%CD%&lt;/span&gt;&lt;span class="s2"&gt;\vc\bin"&lt;/span&gt;
&lt;span class="nb"&gt;robocopy&lt;/span&gt; &lt;span class="na"&gt;/mir &lt;/span&gt;&lt;span class="s2"&gt;"C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.43.34808\include"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;%CD%&lt;/span&gt;&lt;span class="s2"&gt;\vc\include"&lt;/span&gt;
&lt;span class="nb"&gt;robocopy&lt;/span&gt; &lt;span class="na"&gt;/mir &lt;/span&gt;&lt;span class="s2"&gt;"C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.43.34808\lib\x64"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;%CD%&lt;/span&gt;&lt;span class="s2"&gt;\vc\lib"&lt;/span&gt;
&lt;span class="nb"&gt;robocopy&lt;/span&gt; &lt;span class="na"&gt;/mir &lt;/span&gt;&lt;span class="s2"&gt;"C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x64"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;%CD%&lt;/span&gt;&lt;span class="s2"&gt;\win\bin"&lt;/span&gt;
&lt;span class="nb"&gt;robocopy&lt;/span&gt; &lt;span class="na"&gt;/mir &lt;/span&gt;&lt;span class="s2"&gt;"C:\Program Files (x86)\Windows Kits\10\Include\10.0.22621.0\shared"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;%CD%&lt;/span&gt;&lt;span class="s2"&gt;\win\include\shared"&lt;/span&gt;
&lt;span class="nb"&gt;robocopy&lt;/span&gt; &lt;span class="na"&gt;/mir &lt;/span&gt;&lt;span class="s2"&gt;"C:\Program Files (x86)\Windows Kits\10\Include\10.0.22621.0\ucrt"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;%CD%&lt;/span&gt;&lt;span class="s2"&gt;\win\include\ucrt"&lt;/span&gt;
&lt;span class="nb"&gt;robocopy&lt;/span&gt; &lt;span class="na"&gt;/mir &lt;/span&gt;&lt;span class="s2"&gt;"C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22621.0\ucrt\x64"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;%CD%&lt;/span&gt;&lt;span class="s2"&gt;\win\lib\ucrt"&lt;/span&gt;
&lt;span class="nb"&gt;robocopy&lt;/span&gt; &lt;span class="na"&gt;/mir &lt;/span&gt;&lt;span class="s2"&gt;"C:\Program Files (x86)\Windows Kits\10\Include\10.0.22621.0\um"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;%CD%&lt;/span&gt;&lt;span class="s2"&gt;\win\include\um"&lt;/span&gt;
&lt;span class="nb"&gt;robocopy&lt;/span&gt; &lt;span class="na"&gt;/mir &lt;/span&gt;&lt;span class="s2"&gt;"C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22621.0\um\x64"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;%CD%&lt;/span&gt;&lt;span class="s2"&gt;\win\lib\um"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then create &lt;code&gt;env.bat&lt;/code&gt; in directory. The purpose of this batch file is to set compiler's environment variables. You can do setup by &lt;code&gt;call&lt;/code&gt;ing it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight batchfile"&gt;&lt;code&gt;@echo &lt;span class="na"&gt;off&lt;/span&gt;
&lt;span class="nb"&gt;pushd&lt;/span&gt; &lt;span class="vm"&gt;%~dp0&lt;/span&gt;
&lt;span class="kd"&gt;set&lt;/span&gt; &lt;span class="kd"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;%CD%&lt;/span&gt;\vc\bin&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="nv"&gt;%CD%&lt;/span&gt;\win\bin&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="nv"&gt;%PATH%&lt;/span&gt;
&lt;span class="kd"&gt;set&lt;/span&gt; &lt;span class="kd"&gt;Include&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;%CD%&lt;/span&gt;\vc\include&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="nv"&gt;%CD%&lt;/span&gt;\win\include\shared&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="nv"&gt;%CD%&lt;/span&gt;\win\include\ucrt&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="nv"&gt;%CD%&lt;/span&gt;\win\include\um&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="nv"&gt;%INCLUDE%&lt;/span&gt;
&lt;span class="kd"&gt;set&lt;/span&gt; &lt;span class="kd"&gt;Lib&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;%CD%&lt;/span&gt;\vc\lib&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="nv"&gt;%CD%&lt;/span&gt;\win\lib\ucrt&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="nv"&gt;%CD%&lt;/span&gt;\win\lib\um&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="nv"&gt;%LIB%&lt;/span&gt;
&lt;span class="nb"&gt;popd&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, use following c code, save as utf-8 encoded &lt;code&gt;test_msvc.c&lt;/code&gt;, in command prompt switch to utf-8 by executing &lt;code&gt;chcp 65001&lt;/code&gt;, and then compile and run it using &lt;code&gt;cl test_msvc.c /link /NODEFAULTLIB msvcrt.lib libvcruntime.lib ucrt.lib kernel32.lib user32.lib &amp;amp;&amp;amp; test_msvc.exe&lt;/code&gt; to test if any files are missing and if ucrt encoding is correct.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;windows.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;puts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello, World!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;puts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"你好，世界！"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;MessageBox&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Hello, World!"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Greetings"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MB_OK&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;EXIT_SUCCESS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;According to &lt;a href="https://learn.microsoft.com/en-us/cpp/porting/upgrade-your-code-to-the-universal-crt?view=msvc-170" rel="noopener noreferrer"&gt;https://learn.microsoft.com/en-us/cpp/porting/upgrade-your-code-to-the-universal-crt?view=msvc-170&lt;/a&gt; and &lt;a href="https://learn.microsoft.com/en-us/cpp/c-runtime-library/crt-library-features?view=msvc-170" rel="noopener noreferrer"&gt;https://learn.microsoft.com/en-us/cpp/c-runtime-library/crt-library-features?view=msvc-170&lt;/a&gt;, c runtime of msvc has been divided into three parts. Above compilation command is best way to generate smallest size without dependency &lt;code&gt;vcruntime140.dll&lt;/code&gt; (all others are dynamically linked).&lt;/p&gt;

</description>
      <category>c</category>
      <category>cpp</category>
      <category>microsoft</category>
      <category>programming</category>
    </item>
    <item>
      <title>Banana NoMake, only one .h required, direct write script with C, replace those annoying gmake, nmake, cmake...</title>
      <dc:creator>shajunxing</dc:creator>
      <pubDate>Thu, 15 May 2025 13:24:50 +0000</pubDate>
      <link>https://dev.to/shajunxing/banana-makezhi-yong-ge-makehwen-jian-qu-dai-na-xie-ling-ren-sheng-yan-de-gmake-nmake-cmakegou-jian-xi-tong-k81</link>
      <guid>https://dev.to/shajunxing/banana-makezhi-yong-ge-makehwen-jian-qu-dai-na-xie-ling-ren-sheng-yan-de-gmake-nmake-cmakegou-jian-xi-tong-k81</guid>
      <description>&lt;p&gt;This article is openly licensed via &lt;a href="https://creativecommons.org/licenses/by-nc-nd/4.0/" rel="noopener noreferrer"&gt;CC BY-NC-ND 4.0&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Project Address: &lt;a href="https://github.com/shajunxing/banana-nomake" rel="noopener noreferrer"&gt;https://github.com/shajunxing/banana-nomake&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I don't like those build systems, I think they break their own belief "mechanism better than policy" and "keep it simple stupid". Why should one learn those ugly and rigid rules? Wouldn't a Turing-Complete programming language be better? Since C compiler is essential, encapsulate necessary functions into a header file, most important points I summarized as follows: 1. &lt;strong&gt;Recursive traversal of file and directories&lt;/strong&gt;; 2. &lt;strong&gt;Comparison of file timestamps&lt;/strong&gt;; 3. &lt;strong&gt;Serial and parallel execution of commands&lt;/strong&gt;, then I can happily write scripts in C, right? Customers would be happy too, as they won't need to install any additional build systems, they can simply type &lt;code&gt;gcc script.c &amp;amp;&amp;amp; ./a.out&lt;/code&gt; or &lt;code&gt;cl script.c &amp;amp;&amp;amp; script.exe&lt;/code&gt;, isn't it quite easy?&lt;/p&gt;

&lt;p&gt;Brief guide: use &lt;code&gt;listdir&lt;/code&gt; to batch process multiple files in a directory, use &lt;code&gt;max&lt;/code&gt; &lt;code&gt;mtime&lt;/code&gt; to compare file modification times, use &lt;code&gt;append&lt;/code&gt; &lt;code&gt;concat&lt;/code&gt; &lt;code&gt;endswith&lt;/code&gt; &lt;code&gt;equals&lt;/code&gt; &lt;code&gt;format&lt;/code&gt; &lt;code&gt;join&lt;/code&gt; &lt;code&gt;startswith&lt;/code&gt; to handle strings, and use &lt;code&gt;async&lt;/code&gt; &lt;code&gt;await&lt;/code&gt; &lt;code&gt;run&lt;/code&gt; to execute commands.&lt;/p&gt;

&lt;p&gt;For example, in a certain project, source code is in &lt;code&gt;src&lt;/code&gt; directory, compiled intermediate files are in &lt;code&gt;build&lt;/code&gt; directory, and target files are in &lt;code&gt;bin&lt;/code&gt; directory. Since C language string literals support direct concatenation, it's really easy to define file names, directories, and command lines.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#define bin_dir "bin" pathsep
&lt;/span&gt;&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="cp"&gt;#define example_exe bin_dir "example" exeext
&lt;/span&gt;&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="cp"&gt;#ifdef _MSC_VER
&lt;/span&gt;    &lt;span class="cp"&gt;#define cc "cl /nologo /c /W3 /MD /Zp /utf-8 /std:clatest /O2 /Fo"
&lt;/span&gt;    &lt;span class="cp"&gt;#define ld "link /nologo /incremental:no /nodefaultlib /out:"
&lt;/span&gt;&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dependency relationship in traditional makefile, like &lt;code&gt;example_exe: example_obj var_h js_data_h js_common_h&lt;/code&gt;, basically just compares modification times of files before and after colon. If before is older than after, it runs following commands. So, if you write it directly in C, it becomes a lot clearer and more straightforward.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mtime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;example_exe&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;mtime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;example_obj&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;var_h&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;js_data_h&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;js_common_h&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;link_example&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because C is Turing-Complete programming language, it can easily implement more complex and flexible logic, which is something those make systems can't compare to. Here's a complete example where I use &lt;code&gt;async()&lt;/code&gt; and &lt;code&gt;await()&lt;/code&gt; to execute commands concurrently on multiple cores, and it's pretty straightforward in C. On the other hand, even if those make systems could pull it off, configuration rules would be all over the place and hard to understand.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#define bin_dir "bin" pathsep
#define build_dir "build" pathsep
#define src_dir "src" pathsep
#define banana_script_src_dir ".." pathsep "banana-script" pathsep "src" pathsep
#define js_common_h banana_script_src_dir "js-common.h"
#define js_common_c banana_script_src_dir "js-common.c"
#define js_common_obj build_dir "js_common" objext
#define js_data_h banana_script_src_dir "js-data.h"
#define js_data_c banana_script_src_dir "js-data.c"
#define js_data_obj build_dir "js_data" objext
#define var_h src_dir "var.h"
#define var_c src_dir "var.c"
#define var_obj build_dir "var" objext
#define example_c src_dir "example.c"
#define example_obj build_dir "example" objext
#define example_exe bin_dir "example" exeext
#ifdef _MSC_VER
&lt;/span&gt;    &lt;span class="cp"&gt;#define cc "cl /nologo /c /W3 /MD /Zp /utf-8 /std:clatest /O2 /Fo"
&lt;/span&gt;    &lt;span class="cp"&gt;#define ld "link /nologo /incremental:no /nodefaultlib /out:"
&lt;/span&gt;    &lt;span class="cp"&gt;#define extra_libs " msvcrt.lib libvcruntime.lib ucrt.lib kernel32.lib user32.lib"
#elif defined(__GNUC__)
&lt;/span&gt;    &lt;span class="cp"&gt;#define cc "gcc -c -Wall -O3 -o "
&lt;/span&gt;    &lt;span class="cp"&gt;#define ld "gcc -fvisibility=hidden -fvisibility-inlines-hidden -static -static-libgcc -s -Wl,--exclude-all-symbols -o "
&lt;/span&gt;    &lt;span class="cp"&gt;#define extra_libs ""
#else
&lt;/span&gt;    &lt;span class="cp"&gt;#error Only msvc and gcc are supported
#endif
#define compile_js_common cc js_common_obj " " js_common_c
#define compile_js_data cc js_data_obj " " js_data_c
#define compile_var cc var_obj " " var_c
#define compile_example cc example_obj " " example_c
#define link_example ld example_exe " " example_obj " " var_obj " " js_data_obj " " js_common_obj extra_libs
&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;build&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;mkdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bin_dir&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;mkdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;build_dir&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// DON'T compare obj because it is generated asynchronously&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mtime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;js_common_obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;mtime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;js_common_h&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;js_common_c&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;async&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;compile_js_common&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mtime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;js_data_obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;mtime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;js_data_h&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;js_data_c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;js_common_h&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;async&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;compile_js_data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mtime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;var_obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;mtime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;var_h&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;var_c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;js_data_h&lt;/span&gt; &lt;span class="n"&gt;js_common_h&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;async&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;compile_var&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mtime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;example_obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;mtime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;example_c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;var_h&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;js_data_h&lt;/span&gt; &lt;span class="n"&gt;js_common_h&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;async&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;compile_example&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;await&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mtime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;example_exe&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;mtime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;example_obj&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;var_h&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;js_data_h&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;js_common_h&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;link_example&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;cleanup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;dir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;file_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;concat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ext&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file_name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file_name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;listdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cleanup&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;rmdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dir&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;argc&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;EXIT_SUCCESS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;argc&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;equals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="s"&gt;"clean"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;listdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bin_dir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cleanup&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;listdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;build_dir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cleanup&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;EXIT_SUCCESS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;equals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="s"&gt;"-h"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"--help"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Invalid target: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Too many arguments&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Usage: %s [clean|-h|--help]&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;EXIT_FAILURE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Below are detailed API definitions:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Constants&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;const enum compiler_type compiler&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Compiler type, can be one of &lt;code&gt;msvc&lt;/code&gt; &lt;code&gt;gcc&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;#define dllext&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;File extension of shared library, e.g &lt;code&gt;".dll"&lt;/code&gt; &lt;code&gt;".so"&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;#define exeext&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;File extension of executable, e.g &lt;code&gt;".exe"&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;#define libext&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;File extension of library, e.g &lt;code&gt;".lib"&lt;/code&gt; &lt;code&gt;".a"&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;#define objext&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;File extension of compiled object, e.g &lt;code&gt;".obj"&lt;/code&gt; &lt;code&gt;".o"&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;const enum os_type os&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Operating system type, can be one of &lt;code&gt;windows&lt;/code&gt; &lt;code&gt;posix&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;#define pathsep&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;File system path seperator, , e.g &lt;code&gt;"\\"&lt;/code&gt; &lt;code&gt;"/"&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Functions&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;void append(char **dest, ...)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Append multiple strings sequentially to end of &lt;code&gt;dest&lt;/code&gt;, &lt;code&gt;dest&lt;/code&gt; must be dynamically allocated.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;void async(const char *cmd)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Parallel run command line &lt;code&gt;cmd&lt;/code&gt;. Maximum number of workers equals to num of cpu cores. If return value is not 0, print error message and exit program.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;void await()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Wait for all workers to finish.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;char *concat(...)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Concatenate multiple strings, return string should be freed when used up.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;bool endswith(const char *str, ...)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Determine whether &lt;code&gt;str&lt;/code&gt; ends with any of rest parameters.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;bool equals(const char *str, ...)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Determine whether &lt;code&gt;str&lt;/code&gt; are equal to any of rest parameters.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;char *format(const char *fmt, ...)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Format string like &lt;code&gt;printf&lt;/code&gt;, return string should be freed when used up.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;char *join(char *sep, ...)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Join multiple strings by given seperator &lt;code&gt;sep&lt;/code&gt;, return string should be freed when used up.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;void listdir(const char *dir, void (*callback)(const char *dir, const char *base, const char *ext))&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Iterate all items in directory &lt;code&gt;dir&lt;/code&gt;, whether &lt;code&gt;dir&lt;/code&gt; ends with or without path seperator doesn't matter, for each item invoke &lt;code&gt;callback&lt;/code&gt;, set 3 parameters: &lt;code&gt;dir&lt;/code&gt; always ends with path seperator. If item is file, combination is complete file path, &lt;code&gt;ext&lt;/code&gt; will be &lt;code&gt;""&lt;/code&gt; if file has no extension. If is directory, &lt;code&gt;dir&lt;/code&gt; will be subdirectory's full path, &lt;code&gt;base&lt;/code&gt; and &lt;code&gt;ext&lt;/code&gt; will be &lt;code&gt;NULL&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;double max(...)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Take one or more double values, returns maximum one.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;double mtime(...)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Get one or more file modification utc time and returns latest one, value for non-existent file is -DBL_MAX&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;void run(const char *cmd)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Run command line &lt;code&gt;cmd&lt;/code&gt;. If return value is not 0, print error message and exit program.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;bool startswith(const char *str, ...)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Determine whether &lt;code&gt;str&lt;/code&gt; starts with any of rest parameters.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

</description>
      <category>programming</category>
      <category>c</category>
      <category>cpp</category>
    </item>
    <item>
      <title>debian stretch升级bookworm历险记</title>
      <dc:creator>shajunxing</dc:creator>
      <pubDate>Thu, 08 May 2025 15:34:56 +0000</pubDate>
      <link>https://dev.to/shajunxing/debian-stretchsheng-ji-bookwormli-xian-ji-1ol6</link>
      <guid>https://dev.to/shajunxing/debian-stretchsheng-ji-bookwormli-xian-ji-1ol6</guid>
      <description>&lt;p&gt;脑抽升级，其实完全没必要，跑得好好的，升级啥。更改源，apt update，apt full-upgrade，弹出蓝色界面提示什么“xdm”需要重启，是否继续，因为是在图形界面下，我没敢点继续，怕xterm连带被关掉，然后就悲剧了，apt无法再执行，提示glibc版本找不到，估计是apt升级了但是libc没有，dpkg还能跑，firefox等软件已无法打开，只得windows里面packages.debian.org找apt的依赖包，u盘下载拿到linux上，dpkg -i --force-all装，但是依赖实在太多，不停报错。一气之下下载.iso，rufus软件写u盘，u盘启动，到分区阶段犹豫了，我是需要保留/home的，网上查了下，建议备份，但三百多G没那么大的u盘。重启，幸好xwindow还能进，但是u盘需要手工mount了，我一想，u盘里面不是有deb吗，缺啥补啥呗，find ./ -name "&lt;em&gt;...&lt;/em&gt;"搜，dpkg -i --force-all ./.../.../*.deb强制装，提示未配置的，dpkg-reconfigure重新配，apt能跑了，再次apt full-upgrade，提升版本不对，估计iso里的和网上最新的版本不一样，apt --fix-broken install，反正就是dpkg -i --force-all apt --fix-broken install apt full-upgrade来回折腾，缺啥装啥，最好ctrl-alt-f1进文本界面，别在x下面弄，提升什么选择配置文件，选包里自带的，不要选硬盘原有的，相当于全新安装。遇到卡死的，比如配置gconf，ctrl-alt-f2，ps aux | grep "gconf"，然后kill掉那个pid最小的，&lt;/p&gt;

</description>
    </item>
    <item>
      <title>C语言得到变参数量的宏，0参数不会错误返回1，gcc和msvc都测试通过</title>
      <dc:creator>shajunxing</dc:creator>
      <pubDate>Thu, 08 May 2025 15:32:11 +0000</pubDate>
      <link>https://dev.to/shajunxing/cyu-yan-de-dao-bian-can-shu-liang-de-hong-0can-shu-bu-hui-cuo-wu-fan-hui-1gcche-msvcdu-ce-shi-tong-guo-33fe</link>
      <guid>https://dev.to/shajunxing/cyu-yan-de-dao-bian-can-shu-liang-de-hong-0can-shu-bu-hui-cuo-wu-fan-hui-1gcche-msvcdu-ce-shi-tong-guo-33fe</guid>
      <description>&lt;p&gt;参考 &lt;a href="https://stackoverflow.com/questions/2124339/c-preprocessor-va-args-number-of-arguments" rel="noopener noreferrer"&gt;https://stackoverflow.com/questions/2124339/c-preprocessor-va-args-number-of-arguments&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;我原先用的是：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#define _expand(x) x
#define _numargs(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, N, ...) N
#define numargs(...) _expand(_numargs(_, ##__VA_ARGS__, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0))
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;msvc必须要用&lt;code&gt;_expand&lt;/code&gt;套一下，原因据说是参数展开时机问题，但零参数会得到错误结果1，gcc有另外的问题，就是不能使用比如&lt;code&gt;-std=c99&lt;/code&gt; &lt;code&gt;-std=c23&lt;/code&gt;，否则零参数也是1，原因是&lt;code&gt;##&lt;/code&gt;是gcc扩展，参见&lt;a href="https://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html" rel="noopener noreferrer"&gt;https://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html&lt;/a&gt;，而标准c直到c23才加入&lt;code&gt;__VA_OPT__&lt;/code&gt;，有意思的是msvc也支持&lt;code&gt;##&lt;/code&gt;。&lt;/p&gt;

&lt;p&gt;高赞那个用&lt;code&gt;(sizeof((int[]){__VA_ARGS__})/sizeof(int))&lt;/code&gt;的，首先msvc必须高版本，且会报C4047类型不匹配警告，而gcc则是错误无法编译。&lt;/p&gt;

&lt;p&gt;只有下面6赞的回答是完美的，我稍微调整了下，以适配个人风格：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#define _numargs_call(__arg_0, __arg_1) __arg_0 __arg_1
#define _numargs_select(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, __arg_0, ...) __arg_0
#define numargs(...) _numargs_call(_numargs_select, (_, ##__VA_ARGS__, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0))
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;msvc现在是用&lt;code&gt;_numargs_call&lt;/code&gt;套一下，零参数不会出问题了，甚至古老的vs2007/wdk7.1也正常。&lt;/p&gt;

&lt;p&gt;测试代码：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"numargs = %d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;numargs&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"numargs = %d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;numargs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"numargs = %d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;numargs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"numargs = %d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;numargs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"hello"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;EXIT_SUCCESS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;执行&lt;code&gt;cl test.c &amp;amp;&amp;amp; test.exe&lt;/code&gt;或&lt;code&gt;gcc -o test.exe test&lt;br&gt;
.c &amp;amp;&amp;amp; ./test.exe&lt;/code&gt;，结果都是：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;numargs = 0
numargs = 1
numargs = 2
numargs = 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>如何在公共聊天室传递隐密信息</title>
      <dc:creator>shajunxing</dc:creator>
      <pubDate>Thu, 08 May 2025 15:31:27 +0000</pubDate>
      <link>https://dev.to/shajunxing/ru-he-zai-gong-gong-liao-tian-shi-chuan-di-yin-mi-xin-xi-5abe</link>
      <guid>https://dev.to/shajunxing/ru-he-zai-gong-gong-liao-tian-shi-chuan-di-yin-mi-xin-xi-5abe</guid>
      <description>&lt;p&gt;比如你想加某人好友，又不愿意自己或对方帐号打在公屏上让所有人都看到，可以这样做：弄个临时或垃圾邮箱，让对方把帐号发到这个邮箱，同时附上一段随机字串，你收到后，把随机字串发在公屏上，问是他发的吗，如此确认即可。&lt;/p&gt;

&lt;p&gt;当然了，也可以用非对称密钥。&lt;/p&gt;

</description>
      <category>security</category>
      <category>privacy</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Node.js写的简单的本地子网端口扫描器</title>
      <dc:creator>shajunxing</dc:creator>
      <pubDate>Thu, 08 May 2025 15:30:55 +0000</pubDate>
      <link>https://dev.to/shajunxing/nodejsxie-de-jian-dan-de-ben-di-zi-wang-duan-kou-sao-miao-qi-378b</link>
      <guid>https://dev.to/shajunxing/nodejsxie-de-jian-dan-de-ben-di-zi-wang-duan-kou-sao-miao-qi-378b</guid>
      <description>&lt;p&gt;比如你的手机开了ftp，或者别的电脑开了什么服务，你懒得再过去翻看ip地址，就用这个脚本，自动从你电脑获取ip地址和掩码计算需要扫描的子网地址，然后自动扫描，需要扫哪些端口自己改一下就是了。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;net&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;net&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;os&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;os&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;int2ip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt; &lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ip2int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;int&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;256&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;mask&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;found&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;ifaces&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;networkInterfaces&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;ifname&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;ifaces&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;iface&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ifaces&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;ifname&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;addr&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;iface&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;internal&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;family&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;IPv4&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;ip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nx"&gt;mask&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;netmask&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nx"&gt;found&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;found&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;No usable ipv4 network&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Scanning on&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;mask&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;ip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ip2int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;mask&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ip2int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mask&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;net_num&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ip&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;mask&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;max_host_num&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ip2int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;255.255.255.255&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="nx"&gt;mask&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;host_num&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;host_num&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;max_host_num&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;host_num&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;ip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;int2ip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;net_num&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;host_num&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;port&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2121&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8000&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;socket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;net&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Socket&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1500&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;connect&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Found&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;destroy&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;destroy&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;timeout&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;destroy&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;比如我一般常用8000（http）和2121（ftp），这是我扫出来的结果：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Scanning on 192.168.196.88 255.255.255.0
Found 192.168.196.88 8000
Found 192.168.196.130 2121
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
  </channel>
</rss>
