From fb12bbea3862b2e552a834ab2692d9bacb9e270d Mon Sep 17 00:00:00 2001 From: Xingyu Wang Date: Tue, 18 Aug 2020 21:34:32 +0800 Subject: [PATCH 1/4] PRF --- ...w to Install Itch on Ubuntu and Other Linux Distributions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/published/20200805 How to Install Itch on Ubuntu and Other Linux Distributions.md b/published/20200805 How to Install Itch on Ubuntu and Other Linux Distributions.md index 31af489532..73289b3d7d 100644 --- a/published/20200805 How to Install Itch on Ubuntu and Other Linux Distributions.md +++ b/published/20200805 How to Install Itch on Ubuntu and Other Linux Distributions.md @@ -7,7 +7,7 @@ [#]: via: (https://itsfoss.com/install-itch-linux/) [#]: author: (Abhishek Prakash https://itsfoss.com/author/abhishek/) -如何在 Ubuntu 和其它的 Linux 发现版上安装 Itch +如何在 Ubuntu 和其它的 Linux 发行版上安装 Itch ====== ![][7] From 7c8b72ccd1c325f0198be512d2266b4ce5bd89bf Mon Sep 17 00:00:00 2001 From: DarkSun Date: Wed, 19 Aug 2020 05:01:32 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E9=80=89=E9=A2=98[tech]:=2020200819=20How?= =?UTF-8?q?=20to=20Convert=20Text=20Files=20between=20Unix=20and=20DOS=20(?= =?UTF-8?q?Windows)=20Formats?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit sources/tech/20200819 How to Convert Text Files between Unix and DOS (Windows) Formats.md --- ... between Unix and DOS (Windows) Formats.md | 222 ++++++++++++++++++ 1 file changed, 222 insertions(+) create mode 100644 sources/tech/20200819 How to Convert Text Files between Unix and DOS (Windows) Formats.md diff --git a/sources/tech/20200819 How to Convert Text Files between Unix and DOS (Windows) Formats.md b/sources/tech/20200819 How to Convert Text Files between Unix and DOS (Windows) Formats.md new file mode 100644 index 0000000000..731fe7c436 --- /dev/null +++ b/sources/tech/20200819 How to Convert Text Files between Unix and DOS (Windows) Formats.md @@ -0,0 +1,222 @@ +[#]: collector: (lujun9972) +[#]: translator: ( ) +[#]: reviewer: ( ) +[#]: publisher: ( ) +[#]: url: ( ) +[#]: subject: (How to Convert Text Files between Unix and DOS (Windows) Formats) +[#]: via: (https://www.2daygeek.com/how-to-convert-text-files-between-unix-and-dos-windows-formats/) +[#]: author: (Magesh Maruthamuthu https://www.2daygeek.com/author/magesh/) + +How to Convert Text Files between Unix and DOS (Windows) Formats +====== + +As a Linux administrator, you may have noticed some requests from developers to convert files from DOS format to Unix format, and vice versa. + +This is because these files were created on a Windows system and copied to a Linux system for some reason. + +It’s harmless, but some applications on the Linux system may not understand these new line of characters, so you need to convert them before using it. + +DOS text files comes with carriage return (CR or \r) and line feed (LF or \n) pairs as their newline characters, whereas Unix text files only have line feed as their newline character. + +There are many ways you can convert a DOS text file to a Unix format. + +But I recommend using a special utility called **dos2unix** / **unix2dos** to convert text files between DOS and Unix formats. + + * **dos2unix:** To convert a text files from the DOS format to the Unix format. + * **unix2dos:** To convert a text files from the Unix format to the DOS format. + * **tr, awk and [sed Command][1]:** These can be used for the same purpose + + + +You can easily identify whether the file is DOS format or Unix format using the od (octal dump) command as shown below. + +``` +# od -bc windows.txt +0000000 125 156 151 170 040 151 163 040 141 040 146 162 145 145 040 157 +U n i x i s a f r e e o +0000020 160 145 156 163 157 165 162 143 145 040 157 160 145 162 141 164 +p e n s o u r c e o p e r a t +0000040 151 156 147 040 163 171 163 164 145 155 015 012 123 165 160 145 +i n g s y s t e m \r \n S u p e +0000060 162 040 143 157 155 160 165 164 145 162 163 040 141 162 145 040 +r c o m p u t e r s a r e +0000100 162 165 156 156 151 156 147 040 157 156 040 125 116 111 130 015 +r u n n i n g o n U N I X \r +0000120 012 071 065 045 040 157 146 040 167 145 142 163 151 164 145 163 +\n 9 5 % o f w e b s i t e s +0000140 040 141 162 145 040 162 165 156 156 151 156 147 040 157 156 040 +a r e r u n n i n g o n +0000160 114 151 156 165 170 040 117 123 015 012 101 156 171 164 150 151 +L i n u x O S \r \n A n y t h i +0000200 156 147 040 143 141 156 040 142 145 040 144 157 156 145 040 157 +n g c a n b e d o n e o +0000220 156 040 114 151 156 165 170 015 012 +n L i n u x \r \n +0000231 +``` + +The above output clearly shows that this is a DOS format file because it contains the escape sequence **`\r\n`**. + +At the same time, when you print the file output on your terminal you will get the output below. + +``` +# cat windows.txt +Unix is a free opensource operating system +Super computers are running on UNIX +95% of websites are running on Linux OS +Anything can be done on Linux +``` + +### How to Install dos2unix on Linux + +dos2unix can be easily installed from the distribution official repository. + +For RHEL/CentOS 6/7 systems, use the **[yum command][2]** to install dos2unix. + +``` +$ sudo yum install -y dos2unix +``` + +For RHEL/CentOS 8 and Fedora systems, use the **[dnf command][3]** to install dos2unix. + +``` +$ sudo yum install -y dos2unix +``` + +For Debian based systems, use the **[apt command][4]** or **[apt-get command][5]** to install dos2unix. + +``` +$ sudo apt-get update +$ sudo apt-get install dos2unix +``` + +For openSUSE systems, use the **[zypper command][6]** to install dos2unix. + +``` +$ sudo zypper install -y dos2unix +``` + +### 1) How to Convert DOS file to UNIX format + +The following command converts the “windows.txt” file from DOS to Unix format. + +The modification of this file is to remove the “\r” from each line of the file. + +``` +# dos2unix windows.txt +dos2unix: converting file windows.txt to Unix format … +``` + +``` +# cat windows.txt +0000000 125 156 151 170 040 151 163 040 141 040 146 162 145 145 040 157 +U n i x i s a f r e e o +0000020 160 145 156 163 157 165 162 143 145 040 157 160 145 162 141 164 +p e n s o u r c e o p e r a t +0000040 151 156 147 040 163 171 163 164 145 155 012 123 165 160 145 162 +i n g s y s t e m \n S u p e r +0000060 040 143 157 155 160 165 164 145 162 163 040 141 162 145 040 162 +c o m p u t e r s a r e r +0000100 165 156 156 151 156 147 040 157 156 040 125 116 111 130 012 071 +u n n i n g o n U N I X \n 9 +0000120 065 045 040 157 146 040 167 145 142 163 151 164 145 163 040 141 +5 % o f w e b s i t e s a +0000140 162 145 040 162 165 156 156 151 156 147 040 157 156 040 114 151 +r e r u n n i n g o n L i +0000160 156 165 170 040 117 123 012 101 156 171 164 150 151 156 147 040 +n u x O S \n A n y t h i n g +0000200 143 141 156 040 142 145 040 144 157 156 145 040 157 156 040 114 +c a n b e d o n e o n L +0000220 151 156 165 170 012 +i n u x \n +0000225 +``` + +The above command will overwrite the original file. + +Use the following command if you want to keep the original file. This will save the converted output as a new file. + +``` +# dos2unix -n windows.txt unix.txt +dos2unix: converting file windows.txt to file unix.txt in Unix format … +``` + +### 1a) How to Convert DOS file to UNIX format Using tr Command + +As discussed at the beginning of the article, you can use the tr command to convert the DOS file to Unix format as shown below. + +``` +Syntax: tr -d '\r' < source_file > output_file +``` + +The below tr command converts the “windows.txt” DOS file to Unix format file “unix.txt”. + +``` +# tr -d '\r' < windows.txt >unix.txt +``` + +**Make a note:** You can’t use the tr command to convert a file from Unix format to Windows (DOS). + +### 1b) How to Convert DOS file to UNIX format Using awk Command + +Use the following awk command format to convert a DOS file to a Unix format. + +``` +Syntax: awk '{ sub("\r$", ""); print }' source_file.txt > output_file.txt +``` + +The below awk command converts the “windows.txt” DOS file to Unix format file “unix.txt”. + +``` +# awk '{ sub("\r$", ""); print }' windows.txt > unix.txt +``` + +### 2) How to Convert UNIX file to DOS format + +When you convert a file from UNIX to DOS format, it will add a carriage return (CR or \r) in each of the line. + +``` +# unix2dos unix.txt +unix2dos: converting file unix.txt to DOS format … +``` + +This command will keep the original file. + +``` +# unix2dos -n unix.txt windows.txt +unix2dos: converting file unix.txt to file windows.txt in DOS format … +``` + +### 2a) How to Convert UNIX file to DOS format Using awk Command + +Use the following awk command format to convert UNIX file to DOS format. + +``` +Syntax: awk 'sub("$", "\r")' source_file.txt > output_file.txt +``` + +The below awk command converts the “unix.txt” file to the DOS format file “windows.txt”. + +``` +# awk 'sub("$", "\r")' unix.txt > windows.txt +``` + +-------------------------------------------------------------------------------- + +via: https://www.2daygeek.com/how-to-convert-text-files-between-unix-and-dos-windows-formats/ + +作者:[Magesh Maruthamuthu][a] +选题:[lujun9972][b] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://www.2daygeek.com/author/magesh/ +[b]: https://github.com/lujun9972 +[1]: https://www.2daygeek.com/linux-sed-to-find-and-replace-string-in-files/ +[2]: https://www.2daygeek.com/linux-yum-command-examples-manage-packages-rhel-centos-systems/ +[3]: https://www.2daygeek.com/linux-dnf-command-examples-manage-packages-fedora-centos-rhel-systems/ +[4]: https://www.2daygeek.com/apt-command-examples-manage-packages-debian-ubuntu-systems/ +[5]: https://www.2daygeek.com/apt-get-apt-cache-command-examples-manage-packages-debian-ubuntu-systems/ +[6]: https://www.2daygeek.com/zypper-command-examples-manage-packages-opensuse-system/ From 762b0a8b68570fcb11bf549f4b28516ee55f833c Mon Sep 17 00:00:00 2001 From: DarkSun Date: Wed, 19 Aug 2020 05:04:01 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E9=80=89=E9=A2=98[talk]:=2020200818=20IBM?= =?UTF-8?q?=20details=20next-gen=20POWER10=20processor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit sources/talk/20200818 IBM details next-gen POWER10 processor.md --- ... IBM details next-gen POWER10 processor.md | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 sources/talk/20200818 IBM details next-gen POWER10 processor.md diff --git a/sources/talk/20200818 IBM details next-gen POWER10 processor.md b/sources/talk/20200818 IBM details next-gen POWER10 processor.md new file mode 100644 index 0000000000..4735bd939e --- /dev/null +++ b/sources/talk/20200818 IBM details next-gen POWER10 processor.md @@ -0,0 +1,53 @@ +[#]: collector: (lujun9972) +[#]: translator: ( ) +[#]: reviewer: ( ) +[#]: publisher: ( ) +[#]: url: ( ) +[#]: subject: (IBM details next-gen POWER10 processor) +[#]: via: (https://www.networkworld.com/article/3571415/ibm-details-next-gen-power10-processor.html) +[#]: author: (Andy Patrizio https://www.networkworld.com/author/Andy-Patrizio/) + +IBM details next-gen POWER10 processor +====== +New CPU is optimized for enterprise hybrid cloud and AI inferencing, and it features a new technology for creating petabyte-scale memory clusters. +IBM + +IBM on Monday took the wraps off its latest POWER RISC CPU family, optimized for enterprise hybrid-cloud computing and artificial intelligence (AI) inferencing, along with a number of other improvements. + +Power is the last of the Unix processors from the 1990s, when Sun Microsystems, HP, SGI, and IBM all had competing Unixes and RISC processors to go with them. Unix gave way to Linux and RISC gave way to x86, but IBM holds on. + +This is IBM's first 7-nanometer processor, and IBM claims it will deliver an up-to-three-times improvement in capacity and processor energy efficiency within the same power envelope as its POWER9 predecessor. The processor comes in a 15-core design (actually 16-cores but one is not used) and allows for single or dual chip models, so IBM can put two processors in the same form factor. Each core can have up to eight threads, and each socket supports up to 4TB of memory. + +More interesting is a new memory clustering technology called Memory Inception. This form of clustering allows the system to view memory in another physical server as though it were its own. So instead of putting a lot of memory in each box, servers can literally borrow from their neighbors when there is a spike in demand for memory. Or admins can set up one big server with lots of memory in the middle of a cluster and surround it with low-memory servers that can borrow memory as needed from the high capacity server. + +All of this is done with a latency of 50 to 100 nanoseconds. "This has been a holy grail of the industry for a while now," said William Starke, a distinguished engineer with IBM, on a video conference in advance of the announcement. "Instead of putting a lot of memory in each box, when we have a spike demand for memory I can borrow from my neighbors." + +POWER10 uses something called Open Memory Interfaces (OMI), so the server can use DDR4 now and be upgraded to DDR5 when it hits the market, and it can also use GDDR6 memory used in GPUs. In theory, POWER10 will come with 1TB/sec of memory bandwidth and 1TB/sec of SMP of bandwidth. + +The POWER10 processor has quadruple the number of AES encryption engines per core compared to the POWER9. This enables several security enhancements. First, it means full memory encryption without degradation of performance, so no intruder can scan the contents of memory. + +Second, it enables hardware and software security for containers to provide isolation. This is designed to address new security considerations associated with the higher density of containers. If a container were to be compromised, the POWER10 processor is designed to be able to prevent other containers in the same virtual machine from being affected by the same intrusion. + +Finally, the POWER10 offers in-core AI business inferencing. It achieves this through on-chip support for bfloat16 for training as well as INT8 and INT4, which are commonly used in AI inferencing. This will allow transactional workloads to add AI inferencing in their apps. IBM says the AI inferencing in POWER10 is 20 times that of POWER9. + +Not mentioned in the announcement is operating system support. POWER runs AIX, IBM's flavor of Unix, as well as Linux. That's not too surprising since the news is coming at Hot Chips, the annual semiconductor conference held every year at Stanford University. Hot Chips is focused on the latest chip advances, so software is usually left out. + +IBM generally announces new POWER processors about a year in advance of release, so there is plenty of time for an AIX update. + +Join the Network World communities on [Facebook][1] and [LinkedIn][2] to comment on topics that are top of mind. + +-------------------------------------------------------------------------------- + +via: https://www.networkworld.com/article/3571415/ibm-details-next-gen-power10-processor.html + +作者:[Andy Patrizio][a] +选题:[lujun9972][b] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://www.networkworld.com/author/Andy-Patrizio/ +[b]: https://github.com/lujun9972 +[1]: https://www.facebook.com/NetworkWorld/ +[2]: https://www.linkedin.com/company/network-world From 70d637d6471d2d1c5093b0e1eeb3e1768e16adb0 Mon Sep 17 00:00:00 2001 From: DarkSun Date: Wed, 19 Aug 2020 05:04:40 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E9=80=89=E9=A2=98[tech]:=2020200818=20D=20?= =?UTF-8?q?Declarations=20for=20C=20and=20C++=20Programmers?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit sources/tech/20200818 D Declarations for C and C-- Programmers.md --- ... Declarations for C and C-- Programmers.md | 310 ++++++++++++++++++ 1 file changed, 310 insertions(+) create mode 100644 sources/tech/20200818 D Declarations for C and C-- Programmers.md diff --git a/sources/tech/20200818 D Declarations for C and C-- Programmers.md b/sources/tech/20200818 D Declarations for C and C-- Programmers.md new file mode 100644 index 0000000000..236458f193 --- /dev/null +++ b/sources/tech/20200818 D Declarations for C and C-- Programmers.md @@ -0,0 +1,310 @@ +[#]: collector: (lujun9972) +[#]: translator: ( ) +[#]: reviewer: ( ) +[#]: publisher: ( ) +[#]: url: ( ) +[#]: subject: (D Declarations for C and C++ Programmers) +[#]: via: (https://theartofmachinery.com/2020/08/18/d_declarations_for_c_programmers.html) +[#]: author: (Simon Arneaud https://theartofmachinery.com) + +D Declarations for C and C++ Programmers +====== + +Because D was originally created by a C++ compiler writer, Walter Bright, [it’s an easy language for C and C++ programmers to learn][1], but there are little differences in the way declarations work. I learned them piecemeal in different places, but I’m going to dump a bunch in this one post. + +### `char* p` + +If you want to declare a pointer in C, both of the following work: + +``` +char *p; +char* p; +``` + +Some people prefer the second form because it puts all the type information to one side. At least, that’s what it looks like. Trouble is, you can fall into this trap: + +``` +char* p, q; // Gotcha! p is a pointer to a char, and q is a char in C +``` + +“Type information on the left” isn’t really how C works. D, on the other hand, _does_ put all the type information to the left, so this works the way it appears: + +``` +char* p, q; // Both p and q are of type char* in D +``` + +D also accepts the `char *p` syntax, but the rule I go by is `char *p` when writing C, and `char* p` when writing D, just because that matches how the languages actually work, so no gotchas. + +### Digression: how C declarations work + +This isn’t about D, but helps to make sense of the subtler differences between C and D declarations. + +C declarations are implicit about types. `char *p` doesn’t really say, “`p` is of type `char*`”; it says “the type of `p` is such that `*p` evaluates to a `char`”. Likewise: + +``` +int a[8]; // a[i] evaluates to an int (=> a is an array of ints) +int (*f)(double); // (*f)(0.5) evaluates to an int (=> f is a pointer to a function taking a double, returning an int) +``` + +There’s a kind of theoretical elegance to this implicit approach, but 1) it’s backwards and makes complex types confusing, 2) the theoretical elegance only goes so far because everything’s a special case. For example, `int a[8];` declares an array `a`, but makes the expression `a[8]` undefined. You can only use certain operations, so `int 2*a;` doesn’t work, and neither does `double 1.0 + sin(x);`. The expression `4[a]` is equivalent to `a[4]`, but you can’t declare an array with `int 4[a];`. C++ gave up on the theory when it introduced reference syntax like `int &x;`. + +### `function` and `delegate` + +D has a special `function` keyword for declaring function pointers using the “type information on the left” approach. It makes the declaration of function pointers use the same syntax as the declaration of a function: + +``` +int foo(); +int[] bar(); + +int function() foo_p = &foo; +int[] function() bar_p = &bar; +``` + +Note that the `&` is _required_ to get the address of a function in D (unlike in C and C++). If you want to have an array of pointers, you just add `[]` to the end of the type, just like you do with any other type. Similarly for making pointers to types: + +``` +int function()[] foo_pa = [&foo]; +int function()* foo_pp = &foo_p; +int function()[]* foo_pap = &foo_pa; +``` + +Here’s the C equivalent for comparison: + +``` +int (*foo_p)() = &foo; +int (*foo_pa[])() = {&foo}; +int (**foo_pp)() = &foo_p; +int (*(*foo_pap)[])() = &foo_pa; +``` + +It’s rare to need these complicated types, but the logic for the D declarations is much simpler. + +There’s also the `delegate` keyword, which works in exactly the same way for [“fat function pointers”][2]. + +### Arrays + +The most obvious difference from C is that D uses the “type information on the left” approach: + +``` +// int a[8]; is an error in D +int[8] a; +``` + +Another difference is in the order of indices for multidimensional arrays. E.g., this C code: + +``` +int a[4][64]; +``` + +translates to this in D: + +``` +int[64][4] a; +``` + +Here’s the rule for understanding the D ordering: + +``` +T[4] a; +static assert (is(typeof(a[0]) == T)); +``` + +If `T` represents a type, then `T[4]` is always an array of 4 `T`s. Sounds obvious, but it means that if `T` is `int[64]`, `int[64][4]` must be an array of 4 `int[64]`s. + +### `auto` + +C had `auto` as a storage class keyword since the early days, but it got mostly forgotten because it’s only allowed in the one place it’s the default, anyway. (It effectively means “this variable goes on the stack”.) C++ repurposed the keyword to enable automatic type deduction. + +You can also use `auto` with automatic type deduction in D, but it’s not actually required. Type deduction is always enabled in D; you just need to make your declaration unambiguously a type declaration. For example, these work in D (but not all in C++): + +``` +auto x1 = 42; +const x2 = 42; +static x3 = 42; +``` + +### No need for forward declarations at global scope + +This code works: + +``` +// Legal, but not required in D +// void bar(); + +void foo() +{ + bar(); +} + +void bar() +{ + // ... +} +``` + +Similarly for structs and classes. Order of definition doesn’t matter, and forward declarations aren’t required. + +Order does matter in local scope, though: + +``` +void foo() +{ + // Error! + bar(); + + void bar() + { + // ... + } +} +``` + +Either the definition of `bar()` needs to be put before its usage, or `bar()` needs a forward declaration. + +### `const()` + +The `const` keyword in C declarations can be confusing. (Think `const int *p` vs `int const *p` vs `const int const *p`.) D supports the same syntax, but also allows `const` with parentheses: + +``` +// non-constant pointer to constant int +const(int)* p1; +// constant pointer to constant int +const(int*) p2; +``` + +[`const` is transitive in D][3], anyway, and this syntax makes it much clearer. The same parenthetical syntax works with `immutable`, too. Although C-style syntax is supported by D, I always prefer the parenthetical style for a few more reasons. + +### `ref` + +`ref` is the D alternative to C++’s references. In D, `ref` doesn’t create a new type, it just controls how the instance of the type is stored in memory (i.e, it’s a storage class). C++ acts as if references are types, but references have so many special restrictions that they’re effectively like a complex version of a storage class (in Walter’s words, C++ references try to be both a floor wax and dessert topping). For example, C++ treats `int&` like a type, but forbids declaring an array of `int&`. + +As a former C++ programmer, I used to write D function arguments like this: + +``` +void foo(const ref S s); +``` + +Now I write them like this: + +``` +void foo(ref const(S) s); +``` + +The difference becomes more obvious with more complex types. Treating `ref` like a storage class ends up being cleaner because that’s the way it actually is in D. + +Currently `ref` is only supported with function arguments or `foreach` loop variables, so you can’t declare a regular local variable to be `ref`. + +### Function qualifiers + +D’s backward-compatible support for the C-style `const` keyword creates an unfortunate gotcha: + +``` +struct S +{ + // Confusing! + const int* foo() + { + // ... + } +} +``` + +`foo()` doesn’t return a `const int*`. The `const` applies to the `foo()` member function itself, meaning that it works on `const` instances of `S` and returns a (non-`const`) `int*`. To avoid that trap, I always use the D-style `const()` syntax, and write member function qualifiers on the right: + +``` +struct S +{ + const(int)* foo() + { + // ... + } + + int* bar() const + { + // ... + } +} +``` + +### Syntax ambiguities + +C++ allows initialising struct and class instances without an `=` sign: + +``` +S s(42); +``` + +This syntax famously leads to ambiguities with function declaration syntax in special cases (Scott Meyers’ “most vexing parse”). [People like Herb Sutter have written enough about it.][4] D only supports initialisation with `=`: + +``` +S s = S(42); +// Alternatively: +auto s = S(42); +``` + +C syntax has some weird corners, too. Here’s a simple one: + +``` +x*y; +``` + +That looks like a useless multiplication between two variables, but logically it could be a declaration of `y` as a pointer to a type `x`. Expression and declaration are totally different parses that depend on what the symbol `x` means in this scope. (Even worse, if it’s a declaration, then the new `y` could shadow an existing `y`, which could affect later parses.) So C compilers need to track symbols in a symbol table while parsing, which is why C has forward declarations in practice. + +D sidesteps the ambiguity by requiring a typecast to `void` if you really want to write an arithmetic expression without assigning it to anything: + +``` +int x, y; +cast(void)(x*y); +``` + +I’ve never seen useful code do that, but that rule helps D parse simply without forward declarations. + +Here’s another quirk of C syntax. Remember that C declarations work by having a basic type on the left, followed by expressions that evaluate to that type? C allows parentheses in those expressions, and doesn’t care about whitespace as long as symbols don’t run together. That means these two declarations are equivalent: + +``` +int x; +int(x); +``` + +But what if, instead of `int`, we use some symbol that might be a typedef? + +``` +int main() +{ + // Is this a declaration of x, or a function call? + t(x); +} +``` + +Just for fun, we can exploit shadowing and C’s archaic type rules: + +``` +typedef (*x)(); +main() +{ + x(x); + x(x); +} +``` + +The first line makes `x` a typedef to a function pointer type. The first `x(x);` redeclares `x` to be a function pointer variable, shadowing the typedef. The second `x(x);` is a function call that passes `x` as an argument. Yes, this code actually compiles, but it’s undefined behaviour because the function pointer is dereferenced without being initialised. + +D avoids this chaos thanks to its “all type information on the left” rule. There’s no need to put parentheses around symbols in declarations, so `x(y);` is always a function call. + +-------------------------------------------------------------------------------- + +via: https://theartofmachinery.com/2020/08/18/d_declarations_for_c_programmers.html + +作者:[Simon Arneaud][a] +选题:[lujun9972][b] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]: https://theartofmachinery.com +[b]: https://github.com/lujun9972 +[1]: https://ddili.org/ders/d.en/index.html +[2]: https://tour.dlang.org/tour/en/basics/delegates +[3]: https://dlang.org/articles/const-faq.html#transitive-const +[4]: https://herbsutter.com/2013/05/09/gotw-1-solution/