You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: c/c_notes.html
+252Lines changed: 252 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -666,5 +666,257 @@ <h2 id="variably-modified-array-at-file-scope">Variably modified array at file s
666
666
Or the compiler substitutes it everywhere beforehand?
667
667
If it’s not removed by the optimization phase of the compiler, yes it is evaluated at the runtime.
668
668
That means we shouldn’t take that for granted. We can assume it is evaluated at runtime.</p>
669
+
670
+
<h2id="declaration-of-a-function"><code>static</code> declaration of a function</h2>
671
+
672
+
<p>A function declaration (prototype or even the definition) can omit the keyword <code>static</code> if it comes after another declaration of the same function with <code>static</code>.
673
+
If there is one <code>static</code> declaration of a function, its first declaration has to be <code>static</code>.<br/>
674
+
And a reminder: a function definition serves as a prototype; a prototype serves as a declaration.<br/>
675
+
Normally you will and should have the static in the prototypes too (because they usually come first). </p>
<p>This will print all the supported C/C++ versions by the compiler. Example output - </p>
685
+
686
+
<pre><codeclass="language-plaintext"> -std=c++11 Conform to the ISO 2011 C++ standard.
687
+
-std=c++14 Conform to the ISO 2014 C++ standard.
688
+
revised by the 2003 technical corrigendum.
689
+
-std=c11 Conform to the ISO 2011 C standard.
690
+
-std=c2x Conform to the ISO 202X C standard draft (experimental and incomplete support).
691
+
692
+
</code></pre>
693
+
694
+
<h2id="how-to-pass-a-struct-member-to-without-using-a-variable">How to pass a struct member to <code>sizeof</code> without using a variable?</h2>
695
+
696
+
<p>Let’s say you wanted to use the size of a member of a struct as a buffer size for some other variable/struct but don’t want to create an unnecessary variable of the former struct. </p>
697
+
698
+
<p>One way is to use a macro for the buffer size of both the struct member and the other variable. Example - </p>
<p><code>sizeof(((mystruct *)0)->name)</code> is same as <code>sizeof(((mystruct *)NULL)->name)</code></p>
721
+
722
+
<p>Dereferencing doesn’t take place inside <code>sizeof</code> operator. <code>sizeof</code> operator only sees the type of the operand. </p>
723
+
724
+
<p><code>sizeof</code> infers the type of <code>((mystruct *)0)->name</code>, and returns the size of that type. <code>((mystruct *)0)</code> is just a null pointer of the struct <code>mystruct</code>. <code>0->name</code> is (at compile time) an expression whose type is that of the member <code>name</code>. </p>
725
+
726
+
<p>The code within the <code>sizeof</code> never runs (if it did, the program would segfault!). Only the type of value within the <code>sizeof</code> is looked at. </p>
<h2id="warning-function-declaration-isnt-a-prototype--wstrict-prototypes">Warning: function declaration isn’t a prototype [-Wstrict-prototypes]</h2>
731
+
732
+
<pre><codeclass="language-c">int myfunc();
733
+
734
+
warning: function declaration isn't a prototype [-Wstrict-prototypes]
735
+
11 | int myfunc();
736
+
| ^~~
737
+
</code></pre>
738
+
739
+
<p>A prototype is by definition a function declaration that specifies the type(s) of the function’s argument(s). </p>
740
+
741
+
<p>A non-prototype function declaration like <code>int myfunc();</code> is an old-style declaration that does not specify the number or types of arguments. </p>
742
+
743
+
<p>You can call such a function with any arbitrary number of arguments, and the compiler isn’t required to complain but if the call is inconsistent with the definition, your program has undefined behavior. </p>
744
+
745
+
<p>Logically, empty parentheses would have been a good way to specify that a function takes no arguments, but that syntax was already in use for old-style function declarations, so the ANSI C committee invented a new syntax using the void keyword <code>int myfunc(void);</code></p>
746
+
747
+
<p>A function definition (which includes code for what the function actually does) also provides a declaration. </p>
748
+
749
+
<p>So if you have something like this - </p>
750
+
751
+
<pre><codeclass="language-c">
752
+
int myfunc()
753
+
{
754
+
return 1;
755
+
}
756
+
</code></pre>
757
+
758
+
<p>This provides a non-prototype declaration <code>int myfunc();</code> As a definition, this tells the compiler that testlib has no parameters, but as a declaration, it only tells the compiler that testlib takes some unspecified but fixed number and type(s) of arguments. </p>
759
+
760
+
<p>If you change <code>()</code> to <code>(void)</code> the declaration becomes a prototype. </p>
761
+
762
+
<p>The advantage of a prototype is that if you accidentally call testlib with one or more arguments, the compiler will diagnose the error. </p>
<p>This compiles without error. However, the same approach in C++ gives an error - </p>
842
+
843
+
<pre><codeclass="language-plaintext">source>: In function 'int main()':
844
+
<source>:12:52: error: designator order for field '_mstruct::a' does not match declaration order in 'mstruct' {aka '_mstruct'}
0 commit comments