SlideShare a Scribd company logo
Understand more about C
2016
issue.hsu@gmail.com
An Example
• What will happen if you try to compile, link and run this program?
int main()
{
int a = 42;
printf(“%dn”, a);
}
2
You must #include , add a return 0 and then it
will compile and link. When executed it will
print the value 42 on the screen.
An Example
• What will happen if you try to compile, link and run this program?
int main()
{
int a = 42;
printf(“%dn”, a);
}
3
You probably want to #include which has an
explicit declaration of printf(). The program will
compile, link and run, and it will write the number
42 followed by a newline to the standard output
stream.
A proper C compiler will create an implicit
declaration for the function printf(), compile this
code into an object file.
And when linked with a standard library, it will
find a definition of printf()that accidentally will
match the implicit declaration.
So the program above will actually compile, link
and run.
An Example
• What will happen if you try to compile, link and run this program?
int main()
{
int a = 42;
printf(“%dn”, a);
}
4
If this is C99, the exit value is defined to indicate
success to the runtime environment, just like in
C++98, but for older versions of C, like ANSI C
and K&R, the exit value from this program will be
some undefined garbage value.
But since return values are often passed in a
register I would not be surprised if the garbage
value happens to be 3... since printf() will return
3, the number of characters written to standard
out.
An Example
• What will happen if you try to compile, link and run this program?
int main()
{
int a = 42;
printf(“%dn”, a);
}
5
And talking about C standards... if you want to
show that you care about C programming, you
should use int main(void) as your entry point -
since the standard says so.
Using void to indicate no parameters is essential
for declarations in C, eg a declaration ‘int f();’,
says there is a function f that takes any number
of arguments. While you probably meant to say
‘int f(void);’. Being explicit by using void also for
function definitions does not hurt.
An Example
• Here is what I get when compiling, linking and running the above
program on my machine
6
$ gcc -std=c89 hello1.c
$ ./a.out
42
$ echo $?
3
$ gcc -std=c99 hello1.c
$ ./a.out
42
$ echo $?
0
#include <stdio.h>
int main(void)
{
int a = 42;
printf(“%dn”, a);
}
The default mode for C is now -
std=gnu11 instead of -std=gnu89 in GCC-5
Would it be useful if most of your colleagues
have a deep understanding of the C
programming language they are using?
7
https://algoritmaveprogramlama.files.wordpress.co
m/2013/10/c_pic.png
More C examples
• What is the result of following C code?
8
#include <stdio.h>
void foo(void)
{
int a = 3;
++a;
printf("%dn", a);
}
int main(void)
{
foo();
foo();
foo();
}
More C examples
• What is the result of following C code?
9
#include <stdio.h>
void foo(void)
{
static int a = 3;
++a;
printf("%dn", a);
}
int main(void)
{
foo();
foo();
foo();
}
More C examples
• What is the result of following C code?
10
#include <stdio.h>
void foo(void)
{
static int a;
++a;
printf("%dn", a);
}
int main(void)
{
foo();
foo();
foo();
}
More C examples
• What is the result of following C code?
11
#include <stdio.h>
void foo(void)
{
int a;
++a;
printf("%dn", a);
}
int main(void)
{
foo();
foo();
foo();
}
More C examples
• What is the result of following C code?
12
#include <stdio.h>
static int a;
void foo(void)
{
++a;
printf("%dn", a);
}
int main(void)
{
foo();
foo();
foo();
}
More C examples
• What is the result of following C code?
13
#include <stdio.h>
int a;
void foo(void)
{
++a;
printf("%dn", a);
}
int main(void)
{
foo();
foo();
foo();
}
More C examples
• Can you explain this behavior?
14
#include <stdio.h>
void foo(void)
{
int a;
printf("%dn", a);
}
void bar(void)
{
int a = 42;
}
int main(void)
{
bar();
foo();
}
$ gcc hello3.c && ./a.out
42
$ gcc –O2 hello3.c && ./a.out
0
More C examples
• What about this code snippet?
15
#include <stdio.h>
void foo(void)
{
int a = 41;
a = a++;
printf("%dn", a);
}
int main(void)
{
foo();
}
More C examples
• What about this code snippet?
16
#include <stdio.h>
int b(void) { puts(“3”); return 3; }
int c(void) { puts(“4”); return 4; }
int main(void)
{
int a = b() + c();
printf(“%dn”, a);
}
More C examples
• What do these code snippets print?
17
int a=41; a++; printf("%dn", a);
int a=41; a++ & printf("%dn", a);
int a=41; a++ && printf("%dn", a);
int a=41; if (a++ < 42) printf("%dn", a);
int a=41; a = a++; printf("%dn", a);
SEQUENCE POINT
18
Sequence point
• Sequence point
– https://en.wikipedia.org/wiki/Sequence_point
– A sequence point is a point in the program's execution sequence
where all previous side-effects shall have taken place and where all
subsequent side-effects shall not have taken place
– A lot of developers think C has many sequence points
– The reality is that C has very few sequence points
– This helps to maximize optimization opportunities for the compiler
19
Sequence point
– Between the previous and next sequence point an object shall
have its stored value modified at most once by the evaluation of
an expression.
– Furthermore, the prior value shall be read only to determine the
value to be stored.
20
Sequence point
• In C and C++, sequence points occur in the
following places
– Between evaluation of the left and right operands of the &&
(logical AND), || (logical OR) (as part of short-circuit evaluation),
and comma operators.
• For example, in the expression *p++ != 0 && *q++ != 0, all side effects of the
sub-expression *p++ != 0 are completed before any attempt to access q.
– Between the evaluation of the first operand of the ternary
"question-mark" operator and the second or third operand.
• For example, in the expression a = (*p++) ? (*p++) : 0 there is a sequence
point after the first *p++, meaning it has already been incremented by the time
the second instance is executed.
– At the end of a full expression.
• This category includes expression statements (such as the assignment a=b;),
return statements, the controlling expressions of if, switch, while, or do-while
statements, and all three expressions in a for statement.
21
Sequence point
• In C and C++, sequence points occur in the
following places
– Before a function is entered in a function call.
• The order in which the arguments are evaluated is not specified, but this
sequence point means that all of their side effects are complete before the
function is entered.
• In the expression f(i++) + g(j++) + h(k++), f is called with a parameter of the
original value of i, but i is incremented before entering the body of f. Similarly, j
and k are updated before entering g and h respectively.
• However, it is not specified in which order f(), g(), h() are executed, nor in
which order i, j, k are incremented. Variables j and k in the body of f may or
may not have been already incremented. Note that a function call f(a,b,c) is not
a use of the comma operator and the order of evaluation for a, b, and c is
unspecified.
22
Sequence point
• In C and C++, sequence points occur in the following
places
– At a function return, after the return value is copied into the calling
context. (This sequence point is only specified in the C++
standard; it is present only implicitly in C)
– At the end of an initializer
• for example, after the evaluation of 5 in the declaration int a = 5;.
– Between each declarator in each declarator sequence
• for example, between the two evaluations of a++ in int x = a++, y = a++.
– Aftei the action associated with input/output conversion format
specifier
• For example, in the expression printf(“foo %n %d”, &a, 42), there is a
sequence point after the %n is evaluated before printing 42
23
POINTERS
24
Pointers vs. Arrays
• What is the output of following code?
25
#include <stdio.h>
#include <string.h>
int main()
{
char *p = "hello";
char q[] = "hello";
printf("%zun", sizeof(p));
printf("%zun", sizeof(q));
printf("%zun", strlen(p));
printf("%zun", strlen(q));
return 0;
}
Pointers vs. Arrays
• What is the output of following code?
26
#include <stdio.h>
#include <string.h>
int main()
{
char *p = "hello";
char q[] = "hello";
printf("%zun", sizeof(p));
printf("%zun", sizeof(q));
printf("%zun", strlen(p));
printf("%zun", strlen(q));
return 0;
}
• the sizeof operator
• sizeof(array) returns the amount of
memory used by all elements in array
• sizeof(pointer) only returns the amount of
memory used by the pointer variable itself
• the & operator
• &array is an alias for &array[0] and
returns the address of the first element in
array
• &pointer returns the address of pointer
Pointers vs. Arrays
• What is the output of following code?
27
#include <stdio.h>
#include <string.h>
int main()
{
char *p = "hello";
char q[] = "hello";
printf("%zun", sizeof(p));
printf("%zun", sizeof(q));
printf("%zun", strlen(p));
printf("%zun", strlen(q));
return 0;
}
• a string literal initialization of a character array
• char array[] = “abc” sets the first four
elements in array to ‘a’, ‘b’, ‘c’, and ‘0′
• char *pointer = “abc” sets pointer to the
address of the “abc” string (which may be
stored in read-only memory and thus
unchangeable)
Pointers vs. Arrays
• What is the output of following code?
28
#include <stdio.h>
#include <string.h>
int main()
{
char *p = "hello";
char q[] = "hello";
printf("%zun", sizeof(p));
printf("%zun", sizeof(q));
printf("%zun", strlen(p));
printf("%zun", strlen(q));
return 0;
}
• pointer variable can be
assigned a value whereas
array variable cannot be
• arithmetic on pointer
variable is allowed whereas
array variable is not
Pointers vs. Arrays
• What is the output of following code?
29
#include <stdio.h>
#include <string.h>
void foo(char *p) {
printf("%zun", sizeof(p));
printf("%zun", strlen(p));
}
void bar(char q[]) {
printf("%zun", sizeof(q));
printf("%zun", strlen(q));
}
int main() {
foo("hello");
bar("hello");
return 0;
}
* arrays passed to functions are converted to
pointers
SIZEOF
30
Example of sizeof
• What about this code snippet?
31
#include <stdio.h>
struct X { int a; char b; int c; };
int main(void)
{
printf("%zun", sizeof(int));
printf("%zun", sizeof(char));
printf("%zun", sizeof(struct X));
}
It all depends on the platform and the compile time options
provided. The only thing we know for sure is that sizeof
char is 1
4
1
12
with -fpack-struct option
4
1
9
It is very expensive to work on subword data types,
so the compiler will optimize the code by making
sure that c is on a word boundary by adding some
padding.
Suppose the program is on a 64-bit machine running in 32-
bit compatibility mode
Example of sizeof
• What about this code snippet?
32
#include <stdio.h>
struct X { int a; char b; int c; char d; };
int main(void)
{
printf("%zun", sizeof(int));
printf("%zun", sizeof(char));
printf("%zun", sizeof(struct X));
}
4
1
16
with -fpack-struct option
4
1
10
Example of sizeof
• What about this code snippet?
33
#include <stdio.h>
struct X { int a; char b; int c; char *d; };
int main(void)
{
printf("%zun", sizeof(int));
printf("%zun", sizeof(char));
printf("%zun", sizeof(struct X));
}
4
1
24
with -fpack-struct option
4
1
17
Suppose the program is on a 64-bit
machine running in 64-bit mode
c
b
a
d
24
16
12
8
4
0
ALIGNMENT
34
Alignment issue
35
The legacy code snip is working well in X86 CISC machine
where instructions are available to directly access unaligned
data in memory.
When porting this legacy code from a CISC architecture to
ARM RISC machine, it will have some issues.
• The most common
unaligned access code
#include <stdio.h>
struct X {
int a;
char b;
int c;
char *d;
} __attribute((packed));
int main(void) {
struct X ss;
ss.c = 10;
return ss.c;
}
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0472h/BABFDBCJ.html
Alignment issue
36
The ARM compiler generates assembly language code that
reads the word using an LDR instruction.
If the address is not a multiple of four, the LDR instruction
returns a rotated result rather than performing a true
unaligned word load.
#include <stdio.h>
struct X {
int a;
char b;
int c;
char *d;
} __attribute((packed));
int main(void) {
struct X ss;
ss.c = 10;
return ss.c;
}
0 1 2 3 4 5 6 7 8
Generally, this rotation is not what the programmer
expects.
• The most common
unaligned access code
Alignment issue
37
X86 asm:
.loc 1 11 0
movl $10, -27(%rbp)
.loc 1 12 0
movl -27(%rbp),
%eax
ARMv5 asm:
.loc 1 11 0
ldr r3, [fp, #-16]
and r3, r3, #255
orr r3, r3, #2560
str r3, [fp, #-16]
mov r3, #0
strb r3, [fp, #-12]
.loc 1 12 0
ldr r3, [fp, #-16]
mov r3, r3, lsr #8
ldrb r2, [fp, #-12] @
zero_extendqisi2
mov r2, r2, asl #24
orr r3, r2, r3
mov r0, r3
#include <stdio.h>
struct X {
int a;
char b;
int c;
char *d;
} __attribute((packed));
int main(void) {
struct X ss;
ss.c = 10;
return ss.c;
}
b
a
d
16
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
0
c
• The most common
unaligned access code
Alignment issue
38
ARMv7 asm:
.loc 1 11 0
ldr r3, [fp, #-16]
uxtb r3, r3
orr r3, r3, #2560
str r3, [fp, #-16]
mov r3, #0
strb r3, [fp, #-12]
.loc 1 12 0
ldr r3, [fp, #-15] @
unaligned
mov r0, r3
ARMv5 asm:
.loc 1 11 0
ldr r3, [fp, #-16]
and r3, r3, #255
orr r3, r3, #2560
str r3, [fp, #-16]
mov r3, #0
strb r3, [fp, #-12]
.loc 1 12 0
ldr r3, [fp, #-16]
mov r3, r3, lsr #8
ldrb r2, [fp, #-12] @
zero_extendqisi2
mov r2, r2, asl #24
orr r3, r2, r3
mov r0, r3
#include <stdio.h>
struct X {
int a;
char b;
int c;
char *d;
} __attribute((packed));
int main(void) {
struct X ss;
ss.c = 10;
return ss.c;
}
On ARMv6 and later
architectures, unaligned access
is fully supported.
-munaligned-access
-mno-unaligned-access
Enables (or disables) reading and writing of 16-
and 32- bit values from addresses that are not
16- or 32- bit aligned. By default unaligned
access is disabled for all pre-ARMv6 and all
ARMv6-M architectures, and enabled for all other
architectures.
https://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html
b
a
d
16
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
0
c
• The most common
unaligned access code
Alignment issue
39
#include <stdio.h>
struct X {
int a;
char b;
int c;
char *d;
} __attribute((packed));
int main(void) {
struct X ss;
ss.c = 10;
return ss.c;
}
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0333h/Cdfcgggi.h
tml
• A==1:
• unaligned access causes an Alignment fault Data Abort
exception
• U==0 and A==0:
• if unaligned access, the LDR instruction returns a rotated
result rather than performing a true unaligned word load
• U==1 and A==0:
• unaligned access support for loads and stores of single 16-bit
half-words and 32-bit words
Table L-1 SCTLR.U bit values for different architecture versions in ARM architecture reference
manual
• The most common
unaligned access code
INLINE FUNCTION
40
Inline function
• gcc inlinea.c inlineb.c
– inlineb.c: multiple definition of 'max'
• gcc inlinea.c inlineb.c -O1
– inlineb.c: multiple definition of 'max'
• gcc inlinea.c inlineb.c -std=c99
– inlinea.c: undefined reference to 'max'
– inlineb.c: undefined reference to 'max'
• gcc inlinea.c inlineb.c -std=c99 -O1
– compiled successfully
41
/* inline.h header file */
inline int max(int a, int b)
{
return a > b ? a : b;
}
/* inlinea.c source file */
#include "inline.h“
extern int foo(int a, int
b);
int main(void) {
int a;
a = foo(10,20);
a = max(a,30);
return a;
}
/* inlineb.c source file
*/
#include "inline.h“
int foo(int a, int b) {
int c;
c = max(a,b);
return c;
}
Inline function
• gcc inlinea.c inlineb.c
– inlinea.c: undefined reference to 'max'
– inlineb.c: undefined reference to 'max'
• gcc inlinea.c inlineb.c -O1
– compiled successfully
• gcc inlinea.c inlineb.c -std=c99
– inlineb.c: multiple definition of 'max'
• gcc inlinea.c inlineb.c -std=c99 -O1
– inlineb.c: multiple definition of 'max'
42
/* inline.h header file */
extern inline int max(int a, int b)
{
return a > b ? a : b;
}
/* inlinea.c source file */
#include "inline.h“
extern int foo(int a, int
b);
int main(void) {
int a;
a = foo(10,20);
a = max(a,30);
return a;
}
/* inlineb.c source file
*/
#include "inline.h“
int foo(int a, int b) {
int c;
c = max(a,b);
return c;
}
Inline function
• static inline
– The definition is equal in GNU89 and C99.
– The function will be used in the same translation units. If the function is inlined, the
stand-alone object code is never emitted.
– If the function is not inlined, the stand-alone object code will be emitted, but it can
not be used by other translation units.
• Inline
– In GNU89, no matter the function is inlined, the stand-alone object code will be
emitted, and can be used by other translation units.
– In C99, no matter the function is inlined, the stand-alone object code will not be
emitted.
• extern inline
– In GNU89, no matter the function is inlined, the stand-alone object code will not be
emitted.
– In C99, no matter the function is inlined, the stand-alone object code will be
emitted, and can be used by other translation units.
43
Inline function – Portable model
• gcc inlinea.c inlineb.c
– compiled successfully
• gcc inlinea.c inlineb.c -std=c99
– compiled successfully
• gcc inlinea.c inlineb.c -O1
– compiled successfully
• gcc inlinea.c inlineb.c -std=c99 -O1
– compiled successfully
44
/* inline.h header file */
static inline int max(int a, int b)
{
return a > b ? a : b;
}
/* inlinea.c source file */
#include "inline.h"
extern int foo(int a, int b);
int main(void) {
int a;
a = foo(10,20);
a = max(a,30);
return a;
}
/* inlineb.c source file */
#include "inline.h"
int foo(int a, int b) {
int c;
c = max(a,b);
return c;
}
inlinea.o:
U foo
T main
t max
inlineb.o:
T foo
t max
inlinea.o:
U foo
T main
inlineb.o:
T foo
Inline function –GNU89 model
• gcc inlinea.c inlineb.c
– compiled successfully
• gcc inlinea.c inlineb.c -O1
– compiled successfully
45
/* inline.h header file */
extern inline int max(int a, int b)
{
return a > b ? a : b;
}
/* inlinea.c source file */
#include "inline.h"
extern int foo(int a, int
b);
int main(void) {
int a;
a = foo(10,20);
a = max(a,30);
return a;
}
/* inlineb.c source file
*/
#include "inline.h"
int max(int a, int b);
int foo(int a, int b) {
int c;
c = max(a,b);
return c;
}
inlinea.o:
U foo
T main
inlinea.o:
U foo
T main
U max
inlineb.o:
T foo
T max
inlineb.o:
T foo
T max
Inline function –C99 model
• gcc inlinea.c inlineb.c -std=c99
– compiled successfully
• gcc inlinea.c inlineb.c -std=c99 -O1
– compiled successfully
46
/* inline.h header file */
inline int max(int a, int b) {
return a > b ? a : b;
}
/* inlinea.c source file */
#include "inline.h"
extern int foo(int a, int b);
int main(void) {
int a;
a = foo(10,20);
a = max(a,30);
return a;
}
/* inlineb.c source file */
#include "inline.h"
extern int max(int a, int b);
int foo(int a, int b) {
int c;
c = max(a,b);
return c;
}
inlinea.o:
U foo
T main
U max
inlinea.o:
U foo
T main
inlineb.o:
T foo
T max
inlineb.o:
T foo
T max
References:
http://www.greenend.org.uk/rjk/tech/inline.html
https://gustedt.wordpress.com/2010/11/29/myth-and-reality-about-inline-in-c99/
http://www.drdobbs.com/the-new-c-inline-functions/184401540
https://gcc.gnu.org/onlinedocs/gcc/Inline.html
ADD-ON
47
Volatile type qualifier
• Two functions each executed in a separate thread with the same
pointer as a parameter
48
void add( int *i) {
while (1) {
*i = 0;
for (int a=0; a<10; a++)
(*i)++;
}
}
void check( int *i) {
while (*i != 5) ;
}
void add(volatile int *i) {
while (1) {
*i = 0;
for (int a=0; a<10; a++)
(*i)++;
}
}
void check( int *i) {
while (*i != 5) ;
}
C99 support
References
https://en.wikipedia.org/wiki/Volatile_%28computer_programming%29
https://gcc.gnu.org/onlinedocs/gcc/Volatiles.html
Variable length argument
• http://blog.aaronballman.com/2012/06/how-variable-argument-lists-
work-in-c/
49
#include <stdarg.h>
void foo( int bar, ... )
{
va_list args;
va_start( args, bar );
for (;;) {
some_type t = va_arg( args,
some_type );
/* Do something with t */
}
va_end( args );
}
Nested function
50
#include <stdio.h>
typedef int (*func_t)(int);
static func_t foo(int arg)
{
int nested(int nested_arg)
{
return (arg + nested_arg);
}
return &nested;
}
int main()
{
func_t g = foo(100);
printf("%dn", (*g)(20));
return 0;
}
nested:
access foo frame by ip register
mov r0, #result
bx lr
foo:
load .LTRAMP0 into stack
store the @frame to TRAMP0[2]
store the @nested to TRAMP0[3]
flush cache
mov r0, @TRAMP0
bx lr
main:
bl foo
blx r0
bl printf
bx lr
.word TRAMP0
.word nested
TRAMP0:
ldr ip, [pc, #0]
ldr pc, [pc, #0]
.word 0
.word 0
trampoline
References
https://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html
https://gcc.gnu.org/onlinedocs/gccint/Trampolines.html
http://blog.linux.org.tw/~jserv/archives/2010/07/gcc_nested_func.html
Arrays of length zero
• Arrays of Length Zero
51
#include <stdio.h>
struct X {
int a;
char b;
int c;
char d[0];
};
int main(void) {
printf("%zun", sizeof(struct X));
return 0;
}
#include <stdio.h>
struct X {
int a;
char b;
int c;
char d[];
};
int main(void) {
printf("%zun", sizeof(struct X));
return 0;
}
A real case in linux kernel:
http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/
tree/include/uapi/linux/romfs_fs.h
C99: flexible array memberGNU C support
C90 should have length 1
C99: array of a variable size
d[length], length is runtime define
https://gcc.gnu.org/onlinedocs/gcc/Variable-
Length.html
Restricted pointers (C99)
• What is the issue of the following code?
• Solution:
52
void copy( char *s1, char *s2, int n)
{
while (n--)
*s1++ = *s2++;
}
void copy ( char restrict *s1, char restrict *s2, int
n)
{
while (n--)
*s1++ = *s2++;
}
APPENDIX
53
More about new standard
• C99
– https://en.wikipedia.org/wiki/C99
• C11
– https://en.wikipedia.org/wiki/C11_%28C_standard_revision%29
– http://blog.smartbear.com/codereviewer/c11-a-new-c-standard-
aiming-at-safer-programming/
54
References
• 「你所不知道的 C 語言」系列講座
• Deep C
• Are pointers and arrays equivalent in C?
• Lesser known C features
55

More Related Content

PDF
How A Compiler Works: GNU Toolchain
PDF
Kernel_Crash_Dump_Analysis
PDF
Deep C
PDF
GNU ld的linker script簡介
PDF
The Internals of "Hello World" Program
PDF
from Source to Binary: How GNU Toolchain Works
PPT
Object Oriented Programming Concepts
PPSX
Complete C programming Language Course
How A Compiler Works: GNU Toolchain
Kernel_Crash_Dump_Analysis
Deep C
GNU ld的linker script簡介
The Internals of "Hello World" Program
from Source to Binary: How GNU Toolchain Works
Object Oriented Programming Concepts
Complete C programming Language Course

What's hot (20)

PDF
Insecure coding in C (and C++)
PDF
GDB Rocks!
PDF
Q2.12: Debugging with GDB
PDF
Interpreter, Compiler, JIT from scratch
PDF
用十分鐘 向jserv學習作業系統設計
PPT
Introduction to gdb
PDF
Let's trace Linux Lernel with KGDB @ COSCUP 2021
PDF
ARM Trusted FirmwareのBL31を単体で使う!
PDF
The Microkernel Mach Under NeXTSTEP
PDF
LLVM 總是打開你的心:從電玩模擬器看編譯器應用實例
PDF
What Can Compilers Do for Us?
PDF
COSCUP 2016 - LLVM 由淺入淺
PDF
淺談探索 Linux 系統設計之道
PDF
Modern C++ Explained: Move Semantics (Feb 2018)
PDF
A look into the sanitizer family (ASAN & UBSAN) by Akul Pillai
PDF
Learn C Programming Language by Using GDB
PDF
Vim Rocks!
PDF
C Programming - Refresher - Part I
PDF
Address/Thread/Memory Sanitizer
PDF
Kernel Recipes 2019 - Faster IO through io_uring
Insecure coding in C (and C++)
GDB Rocks!
Q2.12: Debugging with GDB
Interpreter, Compiler, JIT from scratch
用十分鐘 向jserv學習作業系統設計
Introduction to gdb
Let's trace Linux Lernel with KGDB @ COSCUP 2021
ARM Trusted FirmwareのBL31を単体で使う!
The Microkernel Mach Under NeXTSTEP
LLVM 總是打開你的心:從電玩模擬器看編譯器應用實例
What Can Compilers Do for Us?
COSCUP 2016 - LLVM 由淺入淺
淺談探索 Linux 系統設計之道
Modern C++ Explained: Move Semantics (Feb 2018)
A look into the sanitizer family (ASAN & UBSAN) by Akul Pillai
Learn C Programming Language by Using GDB
Vim Rocks!
C Programming - Refresher - Part I
Address/Thread/Memory Sanitizer
Kernel Recipes 2019 - Faster IO through io_uring
Ad

Similar to Understand more about C (20)

PPT
Unit 5 Foc
DOCX
C Programming
PDF
Introduction to programming c and data structures
PDF
Introduction to programming c and data-structures
PDF
7 functions
PPTX
Lecture-2.pptxefygefyeyyegfygcyewvwvvcvywcy
PPT
Fucntions & Pointers in C
PPT
An imperative study of c
DOC
2. operator
PPTX
Introduction to Basic C programming 02
PDF
C programing Tutorial
PPTX
C programming
PPT
Functions and pointers_unit_4
DOCX
Core programming in c
PPTX
What is c
PPT
Basics of c
PPT
Functions and pointers_unit_4
PPTX
Control structure of c
PPTX
the refernce of programming C notes ppt.pptx
Unit 5 Foc
C Programming
Introduction to programming c and data structures
Introduction to programming c and data-structures
7 functions
Lecture-2.pptxefygefyeyyegfygcyewvwvvcvywcy
Fucntions & Pointers in C
An imperative study of c
2. operator
Introduction to Basic C programming 02
C programing Tutorial
C programming
Functions and pointers_unit_4
Core programming in c
What is c
Basics of c
Functions and pointers_unit_4
Control structure of c
the refernce of programming C notes ppt.pptx
Ad

More from Yi-Hsiu Hsu (8)

PPTX
Glow introduction
PPTX
TensorRT survey
PPTX
Yocto Project introduction
PPTX
Introduction to memory order consume
PPTX
RISC-V Introduction
PPTX
Memory model
PPTX
GCC for ARMv8 Aarch64
PPTX
Introduction to armv8 aarch64
Glow introduction
TensorRT survey
Yocto Project introduction
Introduction to memory order consume
RISC-V Introduction
Memory model
GCC for ARMv8 Aarch64
Introduction to armv8 aarch64

Recently uploaded (20)

PDF
top salesforce developer skills in 2025.pdf
PDF
Digital Strategies for Manufacturing Companies
PPTX
Agentic AI : A Practical Guide. Undersating, Implementing and Scaling Autono...
PDF
System and Network Administration Chapter 2
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 41
PPTX
Online Work Permit System for Fast Permit Processing
PDF
How to Choose the Right IT Partner for Your Business in Malaysia
PDF
Flood Susceptibility Mapping Using Image-Based 2D-CNN Deep Learnin. Overview ...
PPTX
Lecture 3: Operating Systems Introduction to Computer Hardware Systems
PPTX
Odoo POS Development Services by CandidRoot Solutions
PPTX
ai tools demonstartion for schools and inter college
PDF
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
PPTX
CHAPTER 2 - PM Management and IT Context
PDF
Odoo Companies in India – Driving Business Transformation.pdf
PPTX
Operating system designcfffgfgggggggvggggggggg
PDF
Wondershare Filmora 15 Crack With Activation Key [2025
PPTX
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
PDF
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
PPT
Introduction Database Management System for Course Database
PDF
How Creative Agencies Leverage Project Management Software.pdf
top salesforce developer skills in 2025.pdf
Digital Strategies for Manufacturing Companies
Agentic AI : A Practical Guide. Undersating, Implementing and Scaling Autono...
System and Network Administration Chapter 2
Internet Downloader Manager (IDM) Crack 6.42 Build 41
Online Work Permit System for Fast Permit Processing
How to Choose the Right IT Partner for Your Business in Malaysia
Flood Susceptibility Mapping Using Image-Based 2D-CNN Deep Learnin. Overview ...
Lecture 3: Operating Systems Introduction to Computer Hardware Systems
Odoo POS Development Services by CandidRoot Solutions
ai tools demonstartion for schools and inter college
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
CHAPTER 2 - PM Management and IT Context
Odoo Companies in India – Driving Business Transformation.pdf
Operating system designcfffgfgggggggvggggggggg
Wondershare Filmora 15 Crack With Activation Key [2025
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
Introduction Database Management System for Course Database
How Creative Agencies Leverage Project Management Software.pdf

Understand more about C

  • 1. Understand more about C 2016 issue.hsu@gmail.com
  • 2. An Example • What will happen if you try to compile, link and run this program? int main() { int a = 42; printf(“%dn”, a); } 2 You must #include , add a return 0 and then it will compile and link. When executed it will print the value 42 on the screen.
  • 3. An Example • What will happen if you try to compile, link and run this program? int main() { int a = 42; printf(“%dn”, a); } 3 You probably want to #include which has an explicit declaration of printf(). The program will compile, link and run, and it will write the number 42 followed by a newline to the standard output stream. A proper C compiler will create an implicit declaration for the function printf(), compile this code into an object file. And when linked with a standard library, it will find a definition of printf()that accidentally will match the implicit declaration. So the program above will actually compile, link and run.
  • 4. An Example • What will happen if you try to compile, link and run this program? int main() { int a = 42; printf(“%dn”, a); } 4 If this is C99, the exit value is defined to indicate success to the runtime environment, just like in C++98, but for older versions of C, like ANSI C and K&R, the exit value from this program will be some undefined garbage value. But since return values are often passed in a register I would not be surprised if the garbage value happens to be 3... since printf() will return 3, the number of characters written to standard out.
  • 5. An Example • What will happen if you try to compile, link and run this program? int main() { int a = 42; printf(“%dn”, a); } 5 And talking about C standards... if you want to show that you care about C programming, you should use int main(void) as your entry point - since the standard says so. Using void to indicate no parameters is essential for declarations in C, eg a declaration ‘int f();’, says there is a function f that takes any number of arguments. While you probably meant to say ‘int f(void);’. Being explicit by using void also for function definitions does not hurt.
  • 6. An Example • Here is what I get when compiling, linking and running the above program on my machine 6 $ gcc -std=c89 hello1.c $ ./a.out 42 $ echo $? 3 $ gcc -std=c99 hello1.c $ ./a.out 42 $ echo $? 0 #include <stdio.h> int main(void) { int a = 42; printf(“%dn”, a); } The default mode for C is now - std=gnu11 instead of -std=gnu89 in GCC-5
  • 7. Would it be useful if most of your colleagues have a deep understanding of the C programming language they are using? 7 https://algoritmaveprogramlama.files.wordpress.co m/2013/10/c_pic.png
  • 8. More C examples • What is the result of following C code? 8 #include <stdio.h> void foo(void) { int a = 3; ++a; printf("%dn", a); } int main(void) { foo(); foo(); foo(); }
  • 9. More C examples • What is the result of following C code? 9 #include <stdio.h> void foo(void) { static int a = 3; ++a; printf("%dn", a); } int main(void) { foo(); foo(); foo(); }
  • 10. More C examples • What is the result of following C code? 10 #include <stdio.h> void foo(void) { static int a; ++a; printf("%dn", a); } int main(void) { foo(); foo(); foo(); }
  • 11. More C examples • What is the result of following C code? 11 #include <stdio.h> void foo(void) { int a; ++a; printf("%dn", a); } int main(void) { foo(); foo(); foo(); }
  • 12. More C examples • What is the result of following C code? 12 #include <stdio.h> static int a; void foo(void) { ++a; printf("%dn", a); } int main(void) { foo(); foo(); foo(); }
  • 13. More C examples • What is the result of following C code? 13 #include <stdio.h> int a; void foo(void) { ++a; printf("%dn", a); } int main(void) { foo(); foo(); foo(); }
  • 14. More C examples • Can you explain this behavior? 14 #include <stdio.h> void foo(void) { int a; printf("%dn", a); } void bar(void) { int a = 42; } int main(void) { bar(); foo(); } $ gcc hello3.c && ./a.out 42 $ gcc –O2 hello3.c && ./a.out 0
  • 15. More C examples • What about this code snippet? 15 #include <stdio.h> void foo(void) { int a = 41; a = a++; printf("%dn", a); } int main(void) { foo(); }
  • 16. More C examples • What about this code snippet? 16 #include <stdio.h> int b(void) { puts(“3”); return 3; } int c(void) { puts(“4”); return 4; } int main(void) { int a = b() + c(); printf(“%dn”, a); }
  • 17. More C examples • What do these code snippets print? 17 int a=41; a++; printf("%dn", a); int a=41; a++ & printf("%dn", a); int a=41; a++ && printf("%dn", a); int a=41; if (a++ < 42) printf("%dn", a); int a=41; a = a++; printf("%dn", a);
  • 19. Sequence point • Sequence point – https://en.wikipedia.org/wiki/Sequence_point – A sequence point is a point in the program's execution sequence where all previous side-effects shall have taken place and where all subsequent side-effects shall not have taken place – A lot of developers think C has many sequence points – The reality is that C has very few sequence points – This helps to maximize optimization opportunities for the compiler 19
  • 20. Sequence point – Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression. – Furthermore, the prior value shall be read only to determine the value to be stored. 20
  • 21. Sequence point • In C and C++, sequence points occur in the following places – Between evaluation of the left and right operands of the && (logical AND), || (logical OR) (as part of short-circuit evaluation), and comma operators. • For example, in the expression *p++ != 0 && *q++ != 0, all side effects of the sub-expression *p++ != 0 are completed before any attempt to access q. – Between the evaluation of the first operand of the ternary "question-mark" operator and the second or third operand. • For example, in the expression a = (*p++) ? (*p++) : 0 there is a sequence point after the first *p++, meaning it has already been incremented by the time the second instance is executed. – At the end of a full expression. • This category includes expression statements (such as the assignment a=b;), return statements, the controlling expressions of if, switch, while, or do-while statements, and all three expressions in a for statement. 21
  • 22. Sequence point • In C and C++, sequence points occur in the following places – Before a function is entered in a function call. • The order in which the arguments are evaluated is not specified, but this sequence point means that all of their side effects are complete before the function is entered. • In the expression f(i++) + g(j++) + h(k++), f is called with a parameter of the original value of i, but i is incremented before entering the body of f. Similarly, j and k are updated before entering g and h respectively. • However, it is not specified in which order f(), g(), h() are executed, nor in which order i, j, k are incremented. Variables j and k in the body of f may or may not have been already incremented. Note that a function call f(a,b,c) is not a use of the comma operator and the order of evaluation for a, b, and c is unspecified. 22
  • 23. Sequence point • In C and C++, sequence points occur in the following places – At a function return, after the return value is copied into the calling context. (This sequence point is only specified in the C++ standard; it is present only implicitly in C) – At the end of an initializer • for example, after the evaluation of 5 in the declaration int a = 5;. – Between each declarator in each declarator sequence • for example, between the two evaluations of a++ in int x = a++, y = a++. – Aftei the action associated with input/output conversion format specifier • For example, in the expression printf(“foo %n %d”, &a, 42), there is a sequence point after the %n is evaluated before printing 42 23
  • 25. Pointers vs. Arrays • What is the output of following code? 25 #include <stdio.h> #include <string.h> int main() { char *p = "hello"; char q[] = "hello"; printf("%zun", sizeof(p)); printf("%zun", sizeof(q)); printf("%zun", strlen(p)); printf("%zun", strlen(q)); return 0; }
  • 26. Pointers vs. Arrays • What is the output of following code? 26 #include <stdio.h> #include <string.h> int main() { char *p = "hello"; char q[] = "hello"; printf("%zun", sizeof(p)); printf("%zun", sizeof(q)); printf("%zun", strlen(p)); printf("%zun", strlen(q)); return 0; } • the sizeof operator • sizeof(array) returns the amount of memory used by all elements in array • sizeof(pointer) only returns the amount of memory used by the pointer variable itself • the & operator • &array is an alias for &array[0] and returns the address of the first element in array • &pointer returns the address of pointer
  • 27. Pointers vs. Arrays • What is the output of following code? 27 #include <stdio.h> #include <string.h> int main() { char *p = "hello"; char q[] = "hello"; printf("%zun", sizeof(p)); printf("%zun", sizeof(q)); printf("%zun", strlen(p)); printf("%zun", strlen(q)); return 0; } • a string literal initialization of a character array • char array[] = “abc” sets the first four elements in array to ‘a’, ‘b’, ‘c’, and ‘0′ • char *pointer = “abc” sets pointer to the address of the “abc” string (which may be stored in read-only memory and thus unchangeable)
  • 28. Pointers vs. Arrays • What is the output of following code? 28 #include <stdio.h> #include <string.h> int main() { char *p = "hello"; char q[] = "hello"; printf("%zun", sizeof(p)); printf("%zun", sizeof(q)); printf("%zun", strlen(p)); printf("%zun", strlen(q)); return 0; } • pointer variable can be assigned a value whereas array variable cannot be • arithmetic on pointer variable is allowed whereas array variable is not
  • 29. Pointers vs. Arrays • What is the output of following code? 29 #include <stdio.h> #include <string.h> void foo(char *p) { printf("%zun", sizeof(p)); printf("%zun", strlen(p)); } void bar(char q[]) { printf("%zun", sizeof(q)); printf("%zun", strlen(q)); } int main() { foo("hello"); bar("hello"); return 0; } * arrays passed to functions are converted to pointers
  • 31. Example of sizeof • What about this code snippet? 31 #include <stdio.h> struct X { int a; char b; int c; }; int main(void) { printf("%zun", sizeof(int)); printf("%zun", sizeof(char)); printf("%zun", sizeof(struct X)); } It all depends on the platform and the compile time options provided. The only thing we know for sure is that sizeof char is 1 4 1 12 with -fpack-struct option 4 1 9 It is very expensive to work on subword data types, so the compiler will optimize the code by making sure that c is on a word boundary by adding some padding. Suppose the program is on a 64-bit machine running in 32- bit compatibility mode
  • 32. Example of sizeof • What about this code snippet? 32 #include <stdio.h> struct X { int a; char b; int c; char d; }; int main(void) { printf("%zun", sizeof(int)); printf("%zun", sizeof(char)); printf("%zun", sizeof(struct X)); } 4 1 16 with -fpack-struct option 4 1 10
  • 33. Example of sizeof • What about this code snippet? 33 #include <stdio.h> struct X { int a; char b; int c; char *d; }; int main(void) { printf("%zun", sizeof(int)); printf("%zun", sizeof(char)); printf("%zun", sizeof(struct X)); } 4 1 24 with -fpack-struct option 4 1 17 Suppose the program is on a 64-bit machine running in 64-bit mode c b a d 24 16 12 8 4 0
  • 35. Alignment issue 35 The legacy code snip is working well in X86 CISC machine where instructions are available to directly access unaligned data in memory. When porting this legacy code from a CISC architecture to ARM RISC machine, it will have some issues. • The most common unaligned access code #include <stdio.h> struct X { int a; char b; int c; char *d; } __attribute((packed)); int main(void) { struct X ss; ss.c = 10; return ss.c; } http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0472h/BABFDBCJ.html
  • 36. Alignment issue 36 The ARM compiler generates assembly language code that reads the word using an LDR instruction. If the address is not a multiple of four, the LDR instruction returns a rotated result rather than performing a true unaligned word load. #include <stdio.h> struct X { int a; char b; int c; char *d; } __attribute((packed)); int main(void) { struct X ss; ss.c = 10; return ss.c; } 0 1 2 3 4 5 6 7 8 Generally, this rotation is not what the programmer expects. • The most common unaligned access code
  • 37. Alignment issue 37 X86 asm: .loc 1 11 0 movl $10, -27(%rbp) .loc 1 12 0 movl -27(%rbp), %eax ARMv5 asm: .loc 1 11 0 ldr r3, [fp, #-16] and r3, r3, #255 orr r3, r3, #2560 str r3, [fp, #-16] mov r3, #0 strb r3, [fp, #-12] .loc 1 12 0 ldr r3, [fp, #-16] mov r3, r3, lsr #8 ldrb r2, [fp, #-12] @ zero_extendqisi2 mov r2, r2, asl #24 orr r3, r2, r3 mov r0, r3 #include <stdio.h> struct X { int a; char b; int c; char *d; } __attribute((packed)); int main(void) { struct X ss; ss.c = 10; return ss.c; } b a d 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 c • The most common unaligned access code
  • 38. Alignment issue 38 ARMv7 asm: .loc 1 11 0 ldr r3, [fp, #-16] uxtb r3, r3 orr r3, r3, #2560 str r3, [fp, #-16] mov r3, #0 strb r3, [fp, #-12] .loc 1 12 0 ldr r3, [fp, #-15] @ unaligned mov r0, r3 ARMv5 asm: .loc 1 11 0 ldr r3, [fp, #-16] and r3, r3, #255 orr r3, r3, #2560 str r3, [fp, #-16] mov r3, #0 strb r3, [fp, #-12] .loc 1 12 0 ldr r3, [fp, #-16] mov r3, r3, lsr #8 ldrb r2, [fp, #-12] @ zero_extendqisi2 mov r2, r2, asl #24 orr r3, r2, r3 mov r0, r3 #include <stdio.h> struct X { int a; char b; int c; char *d; } __attribute((packed)); int main(void) { struct X ss; ss.c = 10; return ss.c; } On ARMv6 and later architectures, unaligned access is fully supported. -munaligned-access -mno-unaligned-access Enables (or disables) reading and writing of 16- and 32- bit values from addresses that are not 16- or 32- bit aligned. By default unaligned access is disabled for all pre-ARMv6 and all ARMv6-M architectures, and enabled for all other architectures. https://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html b a d 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 c • The most common unaligned access code
  • 39. Alignment issue 39 #include <stdio.h> struct X { int a; char b; int c; char *d; } __attribute((packed)); int main(void) { struct X ss; ss.c = 10; return ss.c; } http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0333h/Cdfcgggi.h tml • A==1: • unaligned access causes an Alignment fault Data Abort exception • U==0 and A==0: • if unaligned access, the LDR instruction returns a rotated result rather than performing a true unaligned word load • U==1 and A==0: • unaligned access support for loads and stores of single 16-bit half-words and 32-bit words Table L-1 SCTLR.U bit values for different architecture versions in ARM architecture reference manual • The most common unaligned access code
  • 41. Inline function • gcc inlinea.c inlineb.c – inlineb.c: multiple definition of 'max' • gcc inlinea.c inlineb.c -O1 – inlineb.c: multiple definition of 'max' • gcc inlinea.c inlineb.c -std=c99 – inlinea.c: undefined reference to 'max' – inlineb.c: undefined reference to 'max' • gcc inlinea.c inlineb.c -std=c99 -O1 – compiled successfully 41 /* inline.h header file */ inline int max(int a, int b) { return a > b ? a : b; } /* inlinea.c source file */ #include "inline.h“ extern int foo(int a, int b); int main(void) { int a; a = foo(10,20); a = max(a,30); return a; } /* inlineb.c source file */ #include "inline.h“ int foo(int a, int b) { int c; c = max(a,b); return c; }
  • 42. Inline function • gcc inlinea.c inlineb.c – inlinea.c: undefined reference to 'max' – inlineb.c: undefined reference to 'max' • gcc inlinea.c inlineb.c -O1 – compiled successfully • gcc inlinea.c inlineb.c -std=c99 – inlineb.c: multiple definition of 'max' • gcc inlinea.c inlineb.c -std=c99 -O1 – inlineb.c: multiple definition of 'max' 42 /* inline.h header file */ extern inline int max(int a, int b) { return a > b ? a : b; } /* inlinea.c source file */ #include "inline.h“ extern int foo(int a, int b); int main(void) { int a; a = foo(10,20); a = max(a,30); return a; } /* inlineb.c source file */ #include "inline.h“ int foo(int a, int b) { int c; c = max(a,b); return c; }
  • 43. Inline function • static inline – The definition is equal in GNU89 and C99. – The function will be used in the same translation units. If the function is inlined, the stand-alone object code is never emitted. – If the function is not inlined, the stand-alone object code will be emitted, but it can not be used by other translation units. • Inline – In GNU89, no matter the function is inlined, the stand-alone object code will be emitted, and can be used by other translation units. – In C99, no matter the function is inlined, the stand-alone object code will not be emitted. • extern inline – In GNU89, no matter the function is inlined, the stand-alone object code will not be emitted. – In C99, no matter the function is inlined, the stand-alone object code will be emitted, and can be used by other translation units. 43
  • 44. Inline function – Portable model • gcc inlinea.c inlineb.c – compiled successfully • gcc inlinea.c inlineb.c -std=c99 – compiled successfully • gcc inlinea.c inlineb.c -O1 – compiled successfully • gcc inlinea.c inlineb.c -std=c99 -O1 – compiled successfully 44 /* inline.h header file */ static inline int max(int a, int b) { return a > b ? a : b; } /* inlinea.c source file */ #include "inline.h" extern int foo(int a, int b); int main(void) { int a; a = foo(10,20); a = max(a,30); return a; } /* inlineb.c source file */ #include "inline.h" int foo(int a, int b) { int c; c = max(a,b); return c; } inlinea.o: U foo T main t max inlineb.o: T foo t max inlinea.o: U foo T main inlineb.o: T foo
  • 45. Inline function –GNU89 model • gcc inlinea.c inlineb.c – compiled successfully • gcc inlinea.c inlineb.c -O1 – compiled successfully 45 /* inline.h header file */ extern inline int max(int a, int b) { return a > b ? a : b; } /* inlinea.c source file */ #include "inline.h" extern int foo(int a, int b); int main(void) { int a; a = foo(10,20); a = max(a,30); return a; } /* inlineb.c source file */ #include "inline.h" int max(int a, int b); int foo(int a, int b) { int c; c = max(a,b); return c; } inlinea.o: U foo T main inlinea.o: U foo T main U max inlineb.o: T foo T max inlineb.o: T foo T max
  • 46. Inline function –C99 model • gcc inlinea.c inlineb.c -std=c99 – compiled successfully • gcc inlinea.c inlineb.c -std=c99 -O1 – compiled successfully 46 /* inline.h header file */ inline int max(int a, int b) { return a > b ? a : b; } /* inlinea.c source file */ #include "inline.h" extern int foo(int a, int b); int main(void) { int a; a = foo(10,20); a = max(a,30); return a; } /* inlineb.c source file */ #include "inline.h" extern int max(int a, int b); int foo(int a, int b) { int c; c = max(a,b); return c; } inlinea.o: U foo T main U max inlinea.o: U foo T main inlineb.o: T foo T max inlineb.o: T foo T max References: http://www.greenend.org.uk/rjk/tech/inline.html https://gustedt.wordpress.com/2010/11/29/myth-and-reality-about-inline-in-c99/ http://www.drdobbs.com/the-new-c-inline-functions/184401540 https://gcc.gnu.org/onlinedocs/gcc/Inline.html
  • 48. Volatile type qualifier • Two functions each executed in a separate thread with the same pointer as a parameter 48 void add( int *i) { while (1) { *i = 0; for (int a=0; a<10; a++) (*i)++; } } void check( int *i) { while (*i != 5) ; } void add(volatile int *i) { while (1) { *i = 0; for (int a=0; a<10; a++) (*i)++; } } void check( int *i) { while (*i != 5) ; } C99 support References https://en.wikipedia.org/wiki/Volatile_%28computer_programming%29 https://gcc.gnu.org/onlinedocs/gcc/Volatiles.html
  • 49. Variable length argument • http://blog.aaronballman.com/2012/06/how-variable-argument-lists- work-in-c/ 49 #include <stdarg.h> void foo( int bar, ... ) { va_list args; va_start( args, bar ); for (;;) { some_type t = va_arg( args, some_type ); /* Do something with t */ } va_end( args ); }
  • 50. Nested function 50 #include <stdio.h> typedef int (*func_t)(int); static func_t foo(int arg) { int nested(int nested_arg) { return (arg + nested_arg); } return &nested; } int main() { func_t g = foo(100); printf("%dn", (*g)(20)); return 0; } nested: access foo frame by ip register mov r0, #result bx lr foo: load .LTRAMP0 into stack store the @frame to TRAMP0[2] store the @nested to TRAMP0[3] flush cache mov r0, @TRAMP0 bx lr main: bl foo blx r0 bl printf bx lr .word TRAMP0 .word nested TRAMP0: ldr ip, [pc, #0] ldr pc, [pc, #0] .word 0 .word 0 trampoline References https://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html https://gcc.gnu.org/onlinedocs/gccint/Trampolines.html http://blog.linux.org.tw/~jserv/archives/2010/07/gcc_nested_func.html
  • 51. Arrays of length zero • Arrays of Length Zero 51 #include <stdio.h> struct X { int a; char b; int c; char d[0]; }; int main(void) { printf("%zun", sizeof(struct X)); return 0; } #include <stdio.h> struct X { int a; char b; int c; char d[]; }; int main(void) { printf("%zun", sizeof(struct X)); return 0; } A real case in linux kernel: http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/ tree/include/uapi/linux/romfs_fs.h C99: flexible array memberGNU C support C90 should have length 1 C99: array of a variable size d[length], length is runtime define https://gcc.gnu.org/onlinedocs/gcc/Variable- Length.html
  • 52. Restricted pointers (C99) • What is the issue of the following code? • Solution: 52 void copy( char *s1, char *s2, int n) { while (n--) *s1++ = *s2++; } void copy ( char restrict *s1, char restrict *s2, int n) { while (n--) *s1++ = *s2++; }
  • 54. More about new standard • C99 – https://en.wikipedia.org/wiki/C99 • C11 – https://en.wikipedia.org/wiki/C11_%28C_standard_revision%29 – http://blog.smartbear.com/codereviewer/c11-a-new-c-standard- aiming-at-safer-programming/ 54
  • 55. References • 「你所不知道的 C 語言」系列講座 • Deep C • Are pointers and arrays equivalent in C? • Lesser known C features 55

Editor's Notes

  • #32: The instruction set of most processors are optimized for moving a word of data between memory and CPU. Suppose you want to change a value crossing a word boundary, you would need to read two words, mask out the value, change the value, mask and write back two words. Perhaps 10 times slower. Remember, C is focused on execution speed.