Programmation en C Les appels systèmes, les erreurs et la chaine de compilation
John Samuel
CPE Lyon
Année: 2017-2018
Courriel: john(dot)samuel(at)cpe(dot)fr
#define PI 3.14159
float area(
float radius) {
return(PI * radius
* radius);
}
#define PI 3.14159
#include "defs.h"
#ifndef PI // Si PI n'est pas défini
#define PI 3.14159
#endif
float area(
float radius) {
return(PI * radius
* radius);
}
Remarque 1: PI n'est pas une variable Remarque 2: Utilisez l'option gcc -E pour comprendre l'objectif d'un préprocesseur
Erreur: PI n'est pas une variable
#include "defs.h"
#ifndef PI
#define PI 3.14159
#endif
float area(
float radius) {
PI = 3.14;
return(PI * radius
* radius);
}
Error: lvalue required as left operand of assignment
PI = 3.15;
^
#ifndef __OPERATORS_H__
#define __OPERATORS_H__
int
add(
int,
int);
#endif //__OPERATORS_H__
#include
"operators.h" // en-têtes(headers)
#include
"operators.h" // 2eme fois, mais pas d'erreurs
#ifndef PI
#define PI 3.14159
#endif
#ifndef square
#define square(value) value * value
#endif
float area(
float radius) {
return(PI * square(radius));
}
Remarque: Il'n y a pas d'espace entre square et (
struct couleur1{
unsigned char rouge;
unsigned char vert;
unsigned char bleu;
unsigned int count;
};
struct couleur2{
unsigned char rouge;
unsigned int count;
unsigned char vert;
unsigned char bleu;
};
printf(
"size- couleur1: %lu, couleur2: %lu\n",
sizeof(
struct
couleur1),
sizeof(
struct
couleur2));
Question: Quel est l'affichage de ce programme?
#pragma pack(push)
#pragma pack(1) //alignement d'un octet
struct couleur3{
unsigned char rouge;
unsigned char vert;
unsigned char bleu;
unsigned int count;
};
#pragma pack(pop)
printf(
"%lu\n",
sizeof(struct couleur3));
Remarque: L'affichage de ce programme: 7
struct couleur4{ //alignement de 4 octets
unsigned char rouge;
unsigned char vert;
unsigned char bleu;
unsigned char _pad;
unsigned int count;
};
struct couleur5{ //alignement de 4 octets
unsigned char rouge;
unsigned char _pad1[3];
unsigned int count;
unsigned char vert;
unsigned char bleu;
unsigned char _pad2[2];
};
Remarque: Utilisez l'option gcc -Wpadded pour savoir si une structure nécessite du padding our être alignée
struct couleur{
unsigned char rouge;
unsigned char vert;
unsigned char bleu;
unsigned int count;
};
int main() {
struct couleur c1;
struct couleur *scptr = &c1;
c1.bleu = 0xff;
scptr->bleu = 0x01;
printf(
"c1.bleu: %hhx\n", c1.bleu); //0x01
}
struct couleur{
unsigned char rouge;
unsigned char vert;
unsigned char bleu;
unsigned int count;
};
void change(
struct couleur *c) {
c->bleu = 0x01;
}
int main() {
struct couleur c1;
c1.bleu = 0xff;
change(&c1);
printf(
"c1.bleu: %hhx\n", c1.bleu); //0x01
}
struct couleur{
unsigned char rouge;
unsigned char vert;
unsigned char bleu;
unsigned int count;
};
void nochange(
struct couleur c) {
c.bleu = 0x03;
}
int main() {
struct couleur c1;
c1.bleu = 0xff;
nochange(c1);
printf(
"c1.bleu: %hhx\n", c1.bleu); //0xff
}
struct couleur{
unsigned char rouge;
unsigned char vert;
unsigned char bleu;
unsigned int count;
struct couleur *next;
};
int main() {
struct couleur first, c1, c2;
struct couleur *cptr;
first.next = &c1;
c1.next = &c2;
c2.next = NULL;
cptr = &first;
while(cptr != NULL) { //navigation
printf(
"cptr->bleu: %hhx\n", cptr->bleu);
cptr = cptr->next; //prochaine couleur
}
}
struct couleur{
unsigned char rouge;
unsigned char vert;
unsigned char bleu;
unsigned int count;
struct couleur *next;
struct couleur *prev;
};
int main() {
struct couleur first, c1, c2, last;
struct couleur *cptr = &last;
first.next = &c1;
first.prev = NULL;
last.next = NULL;
last.prev = &c2;
c1.next = &c2;
c1.prev = &first;
c2.next = &last;
c2.prev = &c1;
while(cptr != &first) { //navigation
printf(
"cptr->bleu: %hhx\n", cptr->bleu);
cptr = cptr->prev; //prochaine couleur
}
}
int
add(
int
a,
int
b
) {
return
a
+ b;
}
int
subtract(
int
a,
int
b
) {
return
a
- b;
}
int main() {
int (*func)(int, int); //pointeur de function
char op = '-';
int num1 = 20, num2 = 30;
if (op == '+') {
func = add;
}
else {
func = subtract;
}
printf("value: %d\n",func(20, 30));
}
/* Fichier: stats.c
* la taille d'une fichier
* auteur: John Samuel
*/
#include
<stdio.h> // en-têtes(headers)
#include
<sys/types.h>
#include
<sys/stat.h>
#include
<unistd.h>
int main(int argc, char ** argv)
{
struct stat sf;
stat ("./stats.c", &sf);
printf("Taille: %ld octets", sf.st_size);
return 0;
}
#include
<stdio.h> // en-têtes(headers)
#include
<sys/types.h>
#include
<sys/stat.h>
#include
<unistd.h>
#include
<stdlib.h>
int main(int argc, char ** argv)
{
struct stat sf;
int status;
status = stat (argv[1], &sf);
if (status == -1) {
perror("Stats");
return(EXIT_FAILURE);
}
printf("Taille: %ld octets", sf.st_size);
return 0;
}
$ gcc -o stats stats.c
$./stats stats.c
Taille: ... octets
$ echo $?
0
$ gcc -o stats stats.c
$ ./stats nostats
Stats: No such file or directory
$ echo $?
1
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv) {
if (argc < 2) {
printf("Usage: readdir path\n");
return(EXIT_FAILURE);
}
DIR *dirp = opendir(argv[1]);
if (dirp == NULL) {
perror("opendir");
return(EXIT_FAILURE);
}
struct dirent * ent;
while(1) {
ent = readdir(dirp);
if (ent == NULL) {
break;
}
printf("%s\n", ent->d_name);
}
closedir(dirp);
return(0);
}
#define PORT 8089
int main() {
int socketfd;
int bind_status;
struct sockaddr_in server_addr, client_addr;
/*
* Creation of a socket
* AF_INET: IPv4 Internet protocols
* SOCK_STREAM: two-way, connection-based byte streams
*/
socketfd = socket(AF_INET, SOCK_STREAM, 0);
if ( socketfd < 0 ) {
perror("Unable to open a socket");
return -1;
}
//server address details
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(PORT);
server_addr.sin_addr.s_addr = INADDR_ANY;
//Connect to the server
int connect_status = connect(socketfd, (struct sockaddr *)
&server_addr, sizeof(server_addr));
if ( connect_status < 0 ) {
perror("Unable to connect to server");
return -1;
}
int main() {
int socketfd;
int bind_status;
struct sockaddr_in server_addr, client_addr;
/*
* Creation of a socket
* AF_INET: IPv4 Internet protocols
* SOCK_STREAM: two-way, connection-based byte streams
*/
socketfd = socket(AF_INET, SOCK_STREAM, 0);
if ( socketfd < 0 ) {
perror("Unable to open a socket");
return -1;
}
int option = 1;
setsockopt(socketfd, SOL_SOCKET, SO_REUSEADDR,
&option, sizeof(option));
//server address details
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(PORT);
server_addr.sin_addr.s_addr = INADDR_ANY;
bind_status = bind(socketfd, (struct sockaddr *)
&server_addr, sizeof(server_addr));
if (bind_status < 0 ) {
perror("Unable to bind to socket");
return -1;
}
// Start listening to the socket
listen(socketfd, 10);
char data[1024];
int client_addr_len = sizeof(client_addr);
int client_socket_fd = accept(socketfd,
(struct sockaddr *) &client_addr, &client_addr_len);
if(client_socket_fd < 0 ) {
perror("Unable to accept client requests");
return -1;
}
$ gcc -E bonjour.c
$ gcc -fdump-tree-all bonjour.c
$ gcc -fdump-rtl-all bonjour.c
$ gcc -O2 bonjour.c
$ gcc -O3 bonjour.c
Remarque: Autres optimisations: -O1 -O2 -O3 -Os -Ofast -Og
$ gcc -S bonjour.c
$ cat bonjour.s
int main() {
int num = 2 + 3;
return(0);
}
$ gcc -O0 -S add.c
add.s
main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl $5, -4(%rbp)
movl $0, %eax
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
int main() {
int num = 2 + 3;
return(0);
}
$ gcc -O2 -S add.c
add.s
main:
.LFB0:
.cfi_startproc
xorl %eax, %eax
ret
.cfi_endproc
$ gcc -march=i686 -m32 bonjour.c
$ gcc -S -march=i686 -m32 bonjour.c
$ gcc -c client.c
$ gcc -c color.c
$ gcc -o color color.o client.o
$ gcc -c client.c
$ gcc -c color.c
$ gcc -o client client.o color.o
$ vim client.c
$ gcc -c client.c
$ gcc -c client.o color.o
$ vim client.c
$ gcc -c client.c
$ gcc -o client client.o color.o
CC ?= gcc
COBJS ?= client.o color.o
SOBJS ?= server.o color.o
.SUFFIXES: .c .o
SERVER = server
CLIENT = client
all: $(SERVER) $(CLIENT)
$(SERVER): $(SOBJS)
$(CC) -o $(SERVER) $(SOBJS)
$(CLIENT): $(COBJS)
$(CC) -o $(CLIENT) $(COBJS)
.c.o:
$(CC) -c $*.c
$ vim server.c
$ vim client.c
$ vim color.c
$ make
$ vim color.c
$ make