<%- jump_to_l10n_link = url_for(path).replace(theme.post_l10n.from, theme.post_l10n.to) %> EN

Due to Github Pages not supporting custom domain HTTPS, I spent some time today setting up a reverse proxy from Nginx to Github Pages on a VPS. I used a certificate issued by Let’s Encrypt to achieve full HTTPS for the entire site (all external resource links were also changed to HTTPS). Here’s a simple record of the process.

Read more »

C++ provides two logical operators || and && as well as the , (comma) operator in its basic syntax. We can overload these operators in a class, but we should avoid doing that. In this article, I will outline the standard descriptions and the reasons why they should not be overloaded.

In summary, because the built-in || and && have short-circuit evaluation semantics, overloading them turns them into regular function calls, yielding semantics that are entirely different from the built-in || and &&. Furthermore, the , operator has left-to-right evaluation semantics, so if you overload it, it will also become a function call and result in semantics that differ from the built-in version.

Read more »

In the C++14 standard (as well as C++98/11), there is a statement in Annex C Compatibility:

Change: Converting void* to a pointer-to-object type requires casting

1
2
3
4
5
char a[10];
void* b=a;
void foo() {
char* c=b;
}

ISO C will accept this usage of pointer to void being assigned to a pointer to object type. C++ will not.

But why does operator new() return void* and allow assigning to T* without an explicit conversion to T*?

Read more »

In C++, the result of a lambda-expression is called a closure object. This article is not intended to introduce the usage of C++ lambdas (this is covered in detail in “TC++PL” and “C++ Primer,” or you can refer to my previous summary C++11 Syntactic Sugar #lambda Expressions), but rather to analyze how lambda-expression is implemented in Clang from the perspective of LLVM-IR.

Read more »

In the previous article Breaking the Access Control Mechanism of C++ Classes, we briefly mentioned that the member access control of C++ classes (public/protected/private) only limits the accessibility of member names, rather than their visibility. This article mainly analyzes the consequences of this property and how to avoid them.

Read more »

It is well known that class members in C++ can have three access specifiers: public, protected, and private:
[ISO/IEC 14882:2014] A member of a class can be

  • private: that is, its name can be used only by members and friends of the class in which it is declared.
  • protected: that is, its name can be used only by members and friends of the class in which it is declared, by classes derived from that class, and by their friends (see 11.4).
  • public: that is, its name can be used anywhere without access restriction.

From the standard’s intention, it aims to hide implementation details and underlying data of a class, which is encapsulation. However, we can also bypass access restrictions through some special means.

Read more »

Separate an article; previously scattered book reviews were scattered in notes and tweets, and not collected in one place, making indexing inconvenient. In the future, after reading technical books, I will write some comments and put them all here. Since the subjects of the reviews are technical books, mere phrases cannot describe all the technical details. The intent of this article is not “technical notes,” but rather “book reviews,” so I won’t delve too deeply into the technical details described in the books. Instead, I will share my own reading experiences and tips as an ordinary reader. If I express any opinions about certain books, they are my personal evaluations of the books with no intention of demeaning the authors.

Read more »

In C++ programming, one of the most frustrating things is that the compiler does too much behind the backs of programmers. This article compiles various situations and actual behaviors of six special member functions: default constructor, copy/move constructor, copy/move assignment operator, and destructor, as outlined in the C++ Standard ([ISO/IEC 14882:2014]). It can serve as supplementary material for “Inside The C++ Object Model,” enhancing the understanding of compiler implementations through standard descriptions.

Additionally, “Inside The C++ Object Model” mainly describes things from the perspective of “compiler implementation,” but from the “C++ standard” perspective, many things in the book are dependent on compiler implementation. For example, the virtual function table; the standard does not specify how the compiler should implement polymorphic behavior, thus it cannot describe details about the virtual function table.

Moreover, many ambiguous interpretations related to the behavior of “compiler-generated” can be addressed here, which is part of the joy of reading the C++ standard—regardless of whether it’s good or bad, the standard specifications cannot be wrong; all implementations that do not adhere to the standard descriptions are unstandard.

Read more »