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