0

I'm reading Computer Systems: A Programmer's Perspective (Bryant & O'Hallaron). In chapter 2 figure 2.4 it shows the following code

#include <stdio.h>

typedef unsigned char *byte_pointer;

void show_bytes(byte_pointer start, int len){
  int i;
  for(i = 0; i < len; i++)
    printf(" %.2x", start[i]);
  printf("\n");
}

void show_int(int x){
  show_bytes((byte_pointer) &x, sizeof(int));
}

void show_float(float x) {
  show_bytes((byte_pointer) &x, sizeof(float));
}

void show_pointer(void *x){
  show_bytes((byte_pointer) &x, sizeof(void *));
}

Figure 2.4 Code to print the byte representation of program objects. This code uses casting to circumvent the type system. Similar functions are easily defined for other data types

Then using the following method

void test_show_bytes(int val) {
int ival = val;
float fval = (float) ival;
int *pval = &ival;
show_int(ival);
show_float(fval);
show_pointer(pval);
}

According to the book, this test method should print the following on linux 64 if the value is 12345

39 30 00 00
00 e4 40 46
b8 11 e5 ff ff 7f 00 00

However when I run the code I get the following result

39 30 00 00
00 00 00 00
d8 d6 54 c3 fd 7f 00 00

I'm using gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04) The code that I'm running based on the examples from the book I'm pretty new to C, any ideas why my results are different?

#include <stdio.h>

typedef unsigned char *byte_pointer;

nt main(){
  int val =  12345;
  test_show_bytes(val);
}

void test_show_bytes(int val) {
  int ival = val;
  float fval = (float) ival;
  int *pval = &ival;
  show_int(ival);
  show_float(fval);
  show_pointer(pval);
}


void show_bytes(byte_pointer start, int len){
  int i;
  for(i = 0; i < len; i++)
    printf(" %.2x", start[i]);
  printf("\n");
}

void show_int(int x){
  show_bytes((byte_pointer) &x, sizeof(int));
}

void show_float(float x) {
  show_bytes((byte_pointer) &x, sizeof(float));
}

void show_pointer(void *x){
  show_bytes((byte_pointer) &x, sizeof(void *));
}
Csisanyi
  • 669
  • 4
  • 16
  • 1
    Don't you get a load of warnings regarding functions being declared implicitely? If not, enable more warnings in your compiler. For GCC you can do this with command line options `-Wall -Wextra` – Gerhardh Jan 31 '21 at 20:04
  • Does that book really put `main` and `show_all_bytes` above all the other funcions? Try putting it below them. – Gerhardh Jan 31 '21 at 20:07
  • Aside: Each of the 3 show functions could be replaced with the same `show_bytes((byte_pointer) &x, sizeof x);` – chux - Reinstate Monica Jan 31 '21 at 20:23

2 Answers2

1

show_float(fval); is used before seeing the function definition of show_float(float x) - a no-no. Don't do that. Enable all compiler warnings to be more productive.

Compiler guessed the definition as show_float(double x) and so passed the wrong information during the show_float(fval); call.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
0

Thanks, solved.

Yes I had a lot of warnings about implicit declaration of functions and conflicting types. I'm pretty much blind to anything under Error level logs, my bad. I will check out what default argument promotion means in C Putting function declarations in order solved the problem. I just guessed the place of the main function initially. Stupid guess, I have used main() only in OOP languages before, should have read the documentation.

#include <stdio.h>

typedef unsigned char *byte_pointer;

void show_bytes(byte_pointer start, int len){
  int i;
  for(i = 0; i < len; i++)
    printf(" %.2x", start[i]);
  printf("\n");
}

void show_int(int x){
  show_bytes((byte_pointer) &x, sizeof(int));
}

void show_float(float x) {
  show_bytes((byte_pointer) &x, sizeof(float));
}

void show_pointer(void *x){
  show_bytes((byte_pointer) &x, sizeof(void *));
}

void test_show_bytes(int val) {
  int ival = val;
  float fval = (float) ival;
  int *pval = &ival;
  show_int(ival);
  show_float(fval);
  show_pointer(pval);
}

int main(){
  int val =  12345;
  test_show_bytes(val);
}
Csisanyi
  • 669
  • 4
  • 16