1

I have a bit of c code that I've been working on in Xcode on my mac. I then wanted to work with it on a Windows machine and compile it with TinyC. When I run it, the output is different.

Is it possible that this is due to using different compilers?

Thanks!


EDIT 1

The code is a simple script that opens up a wav file to throw all the samples into an array.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>



void read_wav_header(unsigned int *samp_rate, unsigned int *bits_per_samp,
                 unsigned int *num_samp);
void read_wav_data(int *data, unsigned int samp_rate,
               unsigned int bits_per_samp, unsigned int num_samp);
int conv_bit_size(unsigned int in, int bps);



int main(void)
// int read_wav(void)
{


unsigned int samp_rate, bits_per_samp, num_samp;
read_wav_header(&samp_rate, &bits_per_samp, &num_samp);

printf("samp_rate=[%d] bits_per_samp=[%d] num_samp=[%d]\n",
       samp_rate, bits_per_samp, num_samp);

int *data = (int *) malloc(num_samp * sizeof(int));
read_wav_data(data, samp_rate, bits_per_samp, num_samp);

unsigned int i;
// for (i = 0; i < num_samp; ++i) {

for (i = 0; i < 100; ++i) {
    printf("%d\n", data[i]);
}

return EXIT_SUCCESS;
    }

   void read_wav_header(unsigned int *samp_rate, unsigned int *bits_per_samp,
                 unsigned int *num_samp)
{
unsigned char buf[5];

// freopen ("/Users/ericbrotto/Desktop/iPhoneData/tmp/Hack.wav","r",stdin);

 freopen ("C:/Documents and Settings/Eric.Brotto/Desktop/Eric_Other/Files/Hack.wav","r",stdin);



/* ChunkID (RIFF for little-endian, RIFX for big-endian) */
fread(buf, 1, 4, stdin);
buf[4] = '\0';
if (strcmp((char*)buf, "RIFF")) exit(EXIT_FAILURE);


/* ChunkSize */
fread(buf, 1, 4, stdin);

/* Format */
fread(buf, 1, 4, stdin);
buf[4] = '\0';

printf("IS THIS WAVE?  -->%s<--\n",(char*)buf);


if (strcmp((char*)buf, "WAVE")) exit(EXIT_FAILURE);

/* Subchunk1ID */
fread(buf, 1, 4, stdin);
buf[4] = '\0';
printf("IS THIS fmt?  -->%s<--\n",(char*)buf);

if (strcmp((char*)buf, "fmt ")) exit(EXIT_FAILURE);

/* Subchunk1Size (16 for PCM) */
fread(buf, 1, 4, stdin);
if (buf[0] != 16 || buf[1] || buf[2] || buf[3]) exit(EXIT_FAILURE);

/* AudioFormat (PCM = 1, other values indicate compression) */
fread(buf, 1, 2, stdin);
if (buf[0] != 1 || buf[1]) exit(EXIT_FAILURE);

/* NumChannels (Mono = 1, Stereo = 2, etc) */
fread(buf, 1, 2, stdin);
unsigned int num_ch = buf[0] + (buf[1] << 8);
if (num_ch != 1) exit(EXIT_FAILURE);

/* SampleRate (8000, 44100, etc) */
fread(buf, 1, 4, stdin);
*samp_rate = buf[0] + (buf[1] << 8) +
(buf[2] << 16) + (buf[3] << 24);

/* ByteRate (SampleRate * NumChannels * BitsPerSample / 8) */
fread(buf, 1, 4, stdin);
const unsigned int byte_rate = buf[0] + (buf[1] << 8) +
(buf[2] << 16) + (buf[3] << 24);

/* BlockAlign (NumChannels * BitsPerSample / 8) */
fread(buf, 1, 2, stdin);
const unsigned int block_align = buf[0] + (buf[1] << 8);

/* BitsPerSample */
fread(buf, 1, 2, stdin);
*bits_per_samp = buf[0] + (buf[1] << 8);

if (byte_rate != ((*samp_rate * num_ch * *bits_per_samp) >> 3))
    exit(EXIT_FAILURE);

if (block_align != ((num_ch * *bits_per_samp) >> 3))
    exit(EXIT_FAILURE);



/* Subchunk2ID */
// fread reads line by line until the end. 

fread(buf, 1, 4, stdin);
  buf[4] = '\0';

if (strcmp((char*)buf, "data")) exit(EXIT_FAILURE);



/* Subchunk2Size (NumSamples * NumChannels * BitsPerSample / 8) */
fread(buf, 1, 4, stdin);

const unsigned int subchunk2_size = buf[0] + (buf[1] << 8) +
(buf[2] << 16) + (buf[3] << 24);
*num_samp = (subchunk2_size << 3) / (
                                     num_ch * *bits_per_samp);
 }


 void read_wav_data(int *data, unsigned int samp_rate,
               unsigned int bits_per_samp, unsigned int num_samp)
 {

// freopen ("/Users/ericbrotto/Desktop/iPhoneData/tmp/Hack.wav","r",stdin);
 freopen ("C:/Documents and Settings/Eric.Brotto/Desktop/Eric_Other/Files/Hack.wav","r",stdin);

  unsigned char buf;
unsigned int i, j;
for (i=0; i < num_samp; ++i) {
    unsigned int tmp = 0;
    for (j=0; j != bits_per_samp; j+=8) {
        fread(&buf, 1, 1, stdin);           
        tmp += buf << j;
    }
    data[i] = conv_bit_size(tmp, bits_per_samp);
}
 }


 int conv_bit_size(unsigned int in, int bps)
 {
const unsigned int max = (1 << (bps-1)) - 1;
 return in > max ? in - (max<<1) : in; // Supposedly this is not correct: http://ubuntuforums.org/showthread.php?p=10442711
//  return in > max ? in - ((max<<1)+2) : in;

 }

EDIT 2

On my mac it outputs all the samples in the array (ints roughly between -32000 and 32000). Here I get the output you see in the image followed by a few million zeros.

enter image description here

Eric Brotto
  • 53,471
  • 32
  • 129
  • 174
  • What is the output, and what code generates it? – Joe Feb 18 '11 at 13:45
  • It's entirely possible. It depends what code you are writing. Some code is deemed "implementation dependent", which means that results will vary from one compiler to another – vmpstr Feb 18 '11 at 13:45
  • We'll need the output as well. –  Feb 18 '11 at 13:56

2 Answers2

0

Yes. Even assuming that both compilers comply with the ISO standard (which is not necessarily so), there's still a lot of leeway in that standard.

For example, if your program uses implementation defined or locale-specific behaviour, the output can be different.

If whoever wrote the program used undefined behaviour, then that's also a possibility for different output.

Your best bet would be to show us the code for proper analysis.

If you're interested in the sorts of things that can differ, Annex J of C99 (you can downlaod the draft with TC1, 2 and 3 from the bottom of that page - the differences between that and the final product are minimal) lists the portability issues (unspecified, undefined, implementation-defined and locale-specific behaviour).

One thing you may want to be careful of. This may not apply to Tiny C but I know that the Microsoft compilers I've used are one of that class where "r" and "rb" are treated differently in fopen/freopen. If you just specify "r", translation takes place which may give you the wrong data from a binary file such as a wav file.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • see EDIT 1. I hope it's not too much :) – Eric Brotto Feb 18 '11 at 13:56
  • are you suggesting that I use rb instead of r? – Eric Brotto Feb 18 '11 at 14:07
  • @Eric: no, I'm pointing out that it's one _possible_ problem from a cursory glance over your code. There's little chance I'm going to do an in-depth analysis since I normally get paid pretty well for that sort of stuff :-) My advice is to create an incredibly short wav file for debugging so that you're not getting several million zeroes. That will ease your task somewhat. Then it's just a matter of comparing the output. – paxdiablo Feb 18 '11 at 14:12
0

Any reasonably simple code (i.e. printf("Hello World!") should behave the same way in both environments. More exotic expressions are not guaranteed.

Xcode uses gcc, so your code may be using a gnu-specific extension (which is not guaranteed to be portable)

Foo Bah
  • 25,660
  • 5
  • 55
  • 79