Link to home
Start Free TrialLog in
Avatar of tfvg
tfvg

asked on

Simple ordinary C programs, which work under UNIX, cannot compile and work well under Windows XP



 Why simple ordinary C programs ( numerical programs with standard file and console input/output ), which work under UNIX, cannot compile and work well under Windows XP? I have tried to compile said C programs with various compilers ( DJGPP, etc. ) under Windows XP, and also tried it under Cygwin ( UNIX - like environment under Windows, which I have installed on my computer ), but after compilation ( with no warnings ), very simple ordinary programs behave wild, crash or keep hanging forever.

Avatar of mccarl
mccarl
Flag of Australia image

There shouldn't be any general reason for this. If you can post some code, we may be able to help further.
Just because a language has an ANSI standard, that doesn't mean that all compilers behave the same. It just means that given ANSI C, they will all be able to compile it (hopefully).

Sorry if that that sounds vague!

If you give us some examples of code that isn't working and what compilers you're using, perhaps we can try and get them working.

From memory, Unix compilers do have a few functions that don't readily translate on other platforms. "Fork" being one example that springs to mind...
Usually, programs that use standard features and libraries will compile and run fine on all platforms. There are, however, there are subtleties out of the scope of c programming that could affect your programs at runtime. For example, text files on windows by default have cr/lf line endings, while those on unix only have lf line endings. This could, incorrectly handled, cause effects like you described.

Otherwise, it's hard to tell were your problems arise from. Maybe you can simplify one of the programs until the problems no longer occur to nail down the cause.
Some interesting stuff here:

http://stackoverflow.com/questions/2295056/c-program-cross-platform-differences-on-windows-and-unix-os

#pragma code can be difficult to migrate - I had to take an online training course company to task for putting these calls into an ANSI C test!
Avatar of tfvg
tfvg

ASKER


 Said programs are trivial and work well under UNIX. However, they behave wild when compiled and executed under Windows XP. It is highly unlikely that all those compilers which are made to compile C programs under Windows XP ( such as DJGPP, etc ) cannot handle them. Someone would notice that in such a long time and solve the problem. Therefore, the solution should be something trivial, for example to set some environment variable to a proper value. The same should be true regarding
compilation and execution of said programs under Cygwin ( UNIX - like environment under Windows, which I have installed on my computer ).
> It is highly unlikely that all those compilers which are made to compile C programs under Windows XP ( such as DJGPP, etc ) cannot handle them.

You'd think so but I remember doing my first C labs at university. I started on Unix myself and got all kinds of strange results when I tried to move very simple programs over to Borland on a Windows machine.

Even in "standard" C texts, leaf through the first few pages and it will often state that code will have only been tested on a very limited number of compilers.
> Said programs are trivial

If they are so trivial, then like we have all said, post the code and we can help further. Without that you/we are just speculating as to what the problem may be.
Avatar of tfvg

ASKER


 It is highly unlikely that all those compilers which are made to compile C programs under Windows XP ( such as DJGPP, etc ) cannot handle said programs, since someone would notice that in such a long time and solve the problem of compiling and executing the simplest possible C programs. Therefore, the solution should be something trivial, for example to set some environment variable to a proper value. T
 he same should be true regarding compilation and execution of said programs under Cygwin ( UNIX - like environment under Windows, which I have installed on my computer ).
I'm liking your optimism but I can tell you from experience that even simple programs can occasionally require modifications be they going from Unix to Windows or Windows to mainframe.

It might be easier if we have something concrete like a program and a compiler and then we can narrow down the problem as mccarl suggests.
Avatar of tfvg

ASKER


 Said problems are most likely caused by malfunctioning of the programs when they attempt to read from a file, or to write to a file, or to read from the console, such as when command arguments are read. Said input and output operations are trivial and work well under UNIX.

Yes, McNetic has already alluded to these.

There are no compiler/OS level flags I'm aware of that allow you to readily convert a program written on one OS to another. I think you're just going to have to go through it call by call to see where the platform specific problems are. You may ultimately have to add platform specific code for each (file name handling on mainframes for example is completely different than on server).
Avatar of tfvg

ASKER


 There has to be a way for a C program to read from a file, or to write to a file when compiled and executed under Windows XP or Cygwin. I am using standard ways for that. Why that does not work?

Avatar of tfvg

ASKER


 Why standard functions like fread() or fwrite() would not work for a C program to read from a file, or to write to a file when compiled and executed under Windows XP or Cygwin?

SYNOPSIS
            #include <stdio.h>
            size_t fread(void *BUF, size_t SIZE, size_t COUNT,
                FILE *FP);

            #include <stdio.h>
            size_t _fread_r(struct _reent *PTR, void *BUF,
                size_t SIZE, size_t COUNT, FILE *FP);
Are you using character based routines? Just wondering if it might be a problem comparing to EOF as described here (in the EOF pitfall section):

http://en.wikipedia.org/wiki/C_file_input/output
ASKER CERTIFIED SOLUTION
Avatar of rd707
rd707
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of tfvg

ASKER




 My understanding is that said standard functions fread() or fwrite() are not character based routines:

SYNOPSIS
            #include <stdio.h>
            size_t fread(void *BUF, size_t SIZE, size_t COUNT,
                FILE *FP);

            #include <stdio.h>
            size_t _fread_r(struct _reent *PTR, void *BUF,
                size_t SIZE, size_t COUNT, FILE *FP);
Yes, as I said - our posts crossed over.

And it is the correction from text to binary mode which was the essence of the similar problem I posted.
If these are short programs and you already understand them, perhaps try writing them from scratch in the windows compilers to see if this throws any light on the problem.
>> Simple ordinary C programs
>> size_t _fread_r(struct _reent *PTR, void *BUF, size_t SIZE, size_t COUNT, FILE *FP);
Nothing ordinary about _fread_r as it is not in the ISO/IEC 9899:TC2 C standard.
I have Cygwin on XP. Whenever I found your symptoms (in either direction), it is due to erroneous code having undefined behavior. For example, if you overwrite a buffer using one platform, there may be no noticeable effect (until possibly you try to modify the code). But on another compiler, the memory layout may be different, so the same code overwriting the buffer may be clobbering a variable or pointer that is to be used; and then dereferencing that pointer can lead to a segmentation fault.

I hear good things about Valgrind. I should download it myself, but so far I've figured out the problems quickly using the ddd debugger on Cygwin and VS 2010 on XP. But here is the Valgrind link for you:
     http://valgrind.org/

You should be able to identify the cause of the crash using the Windows debugger. If you have erroneous code, you can fix them in Windows VS 2010 and port back the correction to your Unix version.

In case you are unfamiliar with the VS debugger, here are articles that you can use:

C/C++ Beginner's Debugging Guide

After becoming familiar with the basics, move onto these two articles:
   Breakpoint Tips for C/C++

   Watch, Memory, Stack Tips: C/C++
Avatar of tfvg

ASKER


 

 Said programs do not use  size_t _fread_r(struct _reent *PTR, void *BUF, size_t SIZE, size_t COUNT, FILE *FP), they use just fread() ( and fwrite() ).
 Said malfunctioing of said programs is not due to any bugs in the programs, since there are no any bugs in the programs.
 Said malfunctioing of said programs is due to malfunctioing of Windows.

If you are so knowledgeable about what is causing said problems, why are you wasting our time by asking said questions and taking absolutely no said notice of our said responses?
Avatar of tfvg

ASKER


 I just responded to the claims in the previous comments about this matter in order to clarify the issues, since there was a need for it, as it can be seen from said my previous comment.

If you run the Visual Studio 2010 debugger, you can find where the said Windows problems exist in the Windows XP environment. Then you can fix (if you wish) the said problems.

   Good luck!
Avatar of tfvg

ASKER


 If it is so easy to locate the problems in Windows relevant to said issue, and then to develop solutions for them, most likely someone would do that in such a long time, since said problems are the most fundamental.

This is getting us nowhere.

tfvg, I can assure you that if your code is written using standard C, and has no undefined behavior, it'll run fine under Windows.

So, either there is a problem with the code (please post one complete example of code that is misbehaving, so we can have a look at it), or you are using the compilers on Windows wrong (please post the exact steps you took to compile and run that piece of code on Windows, as well as how you did it on Unix).

Without that extra information (both the code and how you compile/run it), we can't help you.
Avatar of tfvg

ASKER


 Said malfunctioning of said programs is not due to any bugs in the programs, since there are no any bugs in the programs, which are simple (some are trivial) and were thoroughly tested. Compiling was done correctly, was trivial (gcc -o name name.c), and the execution and compiling work under UNIX.
  Said malfunctioning of said programs is due to malfunctioning of Windows.

>>   Said malfunctioning of said programs is due to malfunctioning of Windows.

To say it bluntly : no it's not.


>> Said malfunctioning of said programs is not due to any bugs in the programs

I'm pretty sure that the behavior you describe is due to your programs using undefined behavior. Since the code needs to be cross-platform, undefined behavior is basically a bug.


>>  which are simple (some are trivial) and were thoroughly tested.

They were thoroughly tested on Unix, yes. But not on Windows. The tests you did on Unix are unlikely to show the existence of undefined behavior.


I can sense that you are very reluctant to accept the advice we give you. That makes me wonder though, why you asked our help, if you don't trust our expertise ?

Please post one of the simple/trivial pieces of code that works under Unix, but doesn't work under Windows.
>> Why simple ordinary C programs ( numerical programs with standard file and console input/output ), which work under UNIX, cannot compile and work well under Windows XP?
   If it doesn't compile under VS 2010, then you may be able to change switches so that it will compile with no errors/warnings. Likewise, there are switches in Linux that may give warnings where previously you had none (e.g., -Wall). Of course, this assumes that you understand the warnings/errors that you are removing and understand the ramifications in processing.
>>  numerical programs
    I have also experienced that under Linux the same code worked differently under Windows (using VC6). I tracked the problem down to a very slight difference in floating point operations. After researching the problem, I found that the algorithm was slightly unstable in that if I started processing a waveform just one insignificant offset different, then I could get the result of the other platform.

     No need to go into details, as I'm sure you have experienced other numerical issues related to floating point truncation/roundoff issues.

    My report indicated that one was not better than the other. Depending upon the "insignificant" offset into the data, one platform would produce bettre results than the other. By "insignificant", I mean using an offset of only a few bytes into a huge amount of data of sampled analog input.
This may be too obvious, but you say it compiles under cygwin, but are you then trying to run it in cygwin?  Or are you then trying to run it in a windows environment (e.g. DOS command line or double clicking the icon)?
Something compiled in cygwin will only run in cygwin.  You need to use a complier that will create an executiable for the windows environment.  You could try Visual Studio Express or lcc:

http://www.microsoft.com/express/
http://www.cs.virginia.edu/~lcc-win32/
If it doesn't work on the target platform, it hasn't been "thoroughly tested".

You just have to look at the recent case of Microsoft bricking Samsung mobiles with an update to Windows 7 to appreciate this.
Avatar of tfvg

ASKER


   I repeat, said malfunctioning of said programs is not due to any bugs in the programs, since there are no any bugs in the programs, which are simple (some are trivial) and were thoroughly tested. Compiling was done correctly, was trivial (gcc -o name name.c ; gcc -o name name.c –lm ), and the execution and compiling work under UNIX.
  Said malfunctioning of said programs is due to malfunctioning of Windows.
 For example, one short program works perfectly under Windows or Cygwin or UNIX for relatively small size of input data, while under Windows or Cygwin it does not work for large ( 10 MB ) input, while prior to execution there was much more than 10 MB free memory ( 170 MB ). During the execution free memory drops down to 60 MB, but that should not cause the program to execute forever. The program uses malloc() to obtain memory for the data, with error handling function which reports eventual failure of malloc(), and exits. At the end program frees said memory. The (numerical) program itself does not occupy any significant part of the memory. It works perfect under UNIX.
There are no any numerical problems, such as floating point issues, like rounding, algorithm instability or anything like that. That was thoroughly tested under UNIX, and there are no any said critical issues in the program anyway. There is no any undefined behavior in said program. Of course, execution was always performed on the same platform where the compilation was done.
 Simply stated, under Windows or Cygwin executables of some completely correct C programs behave wild.

>>   Said malfunctioning of said programs is due to malfunctioning of Windows.

Extremely unlikely.


>> That was thoroughly tested under UNIX

Right. But as I said before : not under Windows.


>> There is no any undefined behavior in said program.

Hmmm ... I would seriously doubt that. Because this behavior :

>>  Simply stated, under Windows or Cygwin executables of some completely correct C programs behave wild.

is exactly what you'd expect as "undefined behavior".


Look, tfvg. As I said before : you seem to be extremely reluctant to accept our help and trust our expertise. I'm getting the feeling I'm wasting my time here.

If you can post one of those simple programs here, and a description of how it goes "wild", I'll be happy to assist you further. But if you don't, then I can't help you, and I'll go on my way.
Avatar of tfvg

ASKER


 Based on fact and logic reasoning provided in my previous comments, stated above, it is not extremely unlikely that said malfunctioning of said programs is due to malfunctioning of Windows.
 Regarding the fact that said tests of said program were performed under UNIX, said fact proved, as I stated in my previous comment, stated above, that there are no any numerical problems, such as floating point issues, like rounding, algorithm instability or anything like that. That was thoroughly tested under UNIX (and there are no any said critical issues in the program anyway).
 Regarding the fact that there is no any undefined behavior in said program, that was proved by the fact, stated in my previous comment, stated above, that for example, one short program works perfectly under Windows or Cygwin or UNIX for relatively small size of input data, while under Windows or Cygwin it does not work for large ( 10 MB ) input, while prior to execution there was much more than 10 MB free memory ( 170 MB ). During the execution free memory drops down to 60 MB, but that should not cause the program to execute forever. The program uses malloc() to obtain memory for the data, with error handling function which reports eventual failure of malloc(), and exits. At the end program frees said memory. The (numerical) program itself does not occupy any significant part of the memory. It works perfect under UNIX.
 Therefore, simply stated, under Windows or Cygwin executables of some completely correct C programs behave wild. The fact that this is something which can also be a result of programs which have undefined behavior does not matter here, since, as it was proved here above, there is no any undefined behavior in said program.
   Based on the analysis, provided here above, I am not extremely reluctant to accept and trust any expertise offered here, or anywhere else.
    As it can be also seen from said analysis, provided here above, right now there is no need to post one of those simple programs here, and also since I actually did provide a description of how it goes wild, also repeated here.


>>  Regarding the fact that said tests of said program were performed under UNIX, said fact proved

It only proves something about the usage of the software on the platforms you tested it on.
Undefined and platform dependent behavior changes between platforms, so moving the code to a different platform will also change the behavior of the code, if it uses code that has undefined behavior.


>> Regarding the fact that there is no any undefined behavior in said program,

How can you be sure of this "fact" ?

>> that was proved by the fact, stated in my previous comment, stated above, that for example,  <SNIP>

That is NOT a proof ... It just shows that you get lucky some of the time.



>>  Therefore, simply stated, under Windows or Cygwin executables of some completely correct C programs behave wild.

I feel I'm repeating myself, but that is precisely what undefined behavior would cause.



>> Based on the analysis, provided here above, I am not extremely reluctant to accept and trust any expertise offered here, or anywhere else.

So what do you have to lose by indulging me, and posting the code ?
Maybe it'll prove that we're wrong, and then we can move on with this, by considering other possibilities ...
Or maybe it'll show that we're right, and then your problem can be solved, which is what you want, isn't it ?




If you want to keep us guessing (which is essentially what you're doing by not providing the information we ask for), how about I hazard a guess that you have something like this in your code :

        int value;
        fread(&value, sizeof(int), 1, fp);

(or for any type other than int that is not a char).

Note that if my guess is wrong, it does not show that everything else I said is wrong - it just shows that I don't have a working crystal ball in my possession.
Based on your logical reasoning, you conclude that Windows OS is faulty. It may be corrupted, so I suggest a reinstallation (unless you tried this on multiple Windows versions).

As you can see, we have not have problems porting standard code from Linux to Windows and vice-versa if using only standard language components (assuming there are not issues like 32-bit vs 64-bit).

So your specific experience goes against the experience that we have over many years of industry.

Based on your comments thus far, it appears that you do not have the skill to identify the Windows bugs, or you would presumably have mentioned it by now. You may have to contact Windows expertise and bring them in as consultants to solve your problem. Have it in your contract that if the problem is indeed a Windows bug, then you will owe them nothing.

If their consultants say that there is no bug, then you can post their conclusions and the offending code, and we can help defend you if deserved.

If your unix code were acting on struct members violating the standard (e.g., accessing the members in ways other than using . or ->), then that would be an example of how you might have perfect functionality on one system, but fails terribly on another. Then we would have to side with the Windows consultants.

Of course, since you are not able to post the code, it is impossible for me to be sure what your problem is.

I wish you the best of luck in your port. I think I can offer no further advice given the information you have provided.
I second what Infinity08 and phoffric said.
Coming from a Unix C background myself, I have considerable sympathy with tfvg having had similar problems converting to windows, and from windows to mainframe with what I too considered gold code.

However tfvg's unwillingness to entertain the idea that some code changes are required and even more bizarre - unwillingness to post the problematic code leaves us at something of a dead end.

Just to throw something else into the mix, this isn't even a cross-platform issue. When we converted a major project from Borland to VC++ on Win 95, we kept getting a null pointer exception. On inspection, Borland was happily allowing a pointer with an address of 0 to be used without considering it as a null pointer. Strange things can happen between compilers even on the same platform.
I moved onto a project to upgrade the SCO Unix version in a "mature thoroughly" tested program. Not only tested - it had been running perfectly in the field for a decade. We upgraded the SCO version on the same PC platform. There were 1000's of errors. It would have taken several man years to decipher, so we purchased Parasoft's Insure++ to detect run-time memory errors (and more). Then it still took a few man-months to get it "perfect" again. Here we did not switch compiler vendors or OS; just upgrading to newer releases. In every case, we found erroneous code that just happened to be stable and working in the previous environment.
You say you are on Unix (and didn't mention Linux). Are you using Intel CPU having same endianess as in Windows? If not, then that could be a cause of the portability issue.
Avatar of tfvg

ASKER


 As I stated before:

 Regarding the fact that there is no any undefined behavior in said program, that was proved by the fact, stated in my previous comment, stated above, that for example, one short program works perfectly under Windows or Cygwin or UNIX for relatively small size of input data, while under Windows or Cygwin it does not work for large ( 10 MB ) input, while prior to execution there was much more than 10 MB free memory ( 170 MB ). During the execution free memory drops down to 60 MB, but that should not cause the program to execute forever. The program uses malloc() to obtain memory for the data, with error handling function which reports eventual failure of malloc(), and exits. At the end program frees said memory. The (numerical) program itself does not occupy any significant part of the memory. It works perfect under UNIX.

 (end of citation)

 There are no any data structures in the program or parts of the program (code portions) that behave dependent on size of the data which is processed. In addition, program works under UNIX regardless of size of the data which is processed, and there are no any data structures which use pointers, buffers, stacks, etc., during data processing, which can cause problems due to undefined pointers, overlap of stacks, and the like. Files are all opened in binary mode in order to please Windows (there are also error handling functions which report eventual failure to open files). Program first reserves data array in the memory by malloc(), then uses fread() to read the data from the file to said data array, then numerically processes said data, then copies by fwrite() the output from the data array to the output file, then frees the allocated memory and closes the files, and exits (there are also error handling functions which report eventual failure of fread() to read the data or fwrite() to write the data).  In addition, under Cygwin I use the same gcc compiler as under UNIX. The question is: If it works for relatively small size of input data, why it does not work for relatively large ( 10 MB ) input (while prior to execution there was much more than 10 MB free memory ( 170 MB ). During the execution free memory drops down to 60 MB, but that should not cause the program to execute forever)?
 Based on the above, there is no any undefined or platform-dependent behavior in said program, since it works for relatively small size of input data, and for all other reasons described above.

>>  then uses fread() to read the data from the file to said data array, then numerically processes said data

Indeed, which is equivalent to my guess in my previous code : you are extracting data from a file by interpreting a stream of bytes as types other than unsigned char.

That is clearly platform dependent in how it behaves, for several reasons. The most important would be byte ordering, but it also depends on type sizes, internal type representation, etc.

All of these constitute undefined behavior, so (as has been said several times before) :

>>  Based on the above, there is no any undefined or platform-dependent behavior in said program,

There is.

And :

>> since it works for relatively small size of input data, and for all other reasons described above.

That is a false reasoning. You can't disprove the absence of undefined behavior by having it working for one specific case. It's like saying that crossing a busy street without looking is safe, because you did it once without being hit by a car.


Can you now please accept that we know what we're talking about, and that you can trust our judgment ? And can you then please provide the code that we have been asking for so many times ?

I've been very patient up till now, but you're not making it very easy for us to help you.
> The question is: If it works for relatively small size of input data, why it does not work for relatively large

A classic indicator of some kind of memory allocation issue/string overrun etc. As earlier outlined by other experts here - where the compiler chooses to put data and code varies from compiler to compiler. This would tend to point to a code issue.

You can run your program successfully for a billion records (on a large enough machine of course). This does not prove anything - it could still fail on record a billion and one.

As earlier stated by others, there are tools that can weed out this sort of issue - if you're willing to believe it is a coding issue...
>> one short program works perfectly under Windows or Cygwin or UNIX for relatively small size of input data, while under Windows or Cygwin it does not work for large ( 10 MB ) input

This probably has been stated before. Since you are referring to a "short program", it is highly unlikely that it is proprietary in nature. (Or if it is, since it is short, you can easily modify the short program to be generic.

Post the code. It will be very interesting to see good code fail in Windows under XP and Cygwin.
Avatar of tfvg

ASKER


 Infinity08 stated:

 >> then uses fread() to read the data from the file to said data array, then
numerically processes said data

Indeed, which is equivalent to my guess in my previous code : you are extracting data from a file by interpreting a stream of bytes as types other than unsigned char.

That is clearly platform dependent in how it behaves, for several reasons. The most important would be byte ordering, but it also depends on type sizes, internal type representation, etc.

 (end of citation)

 On the contrary, neither fread() nor write() are the cause of the problem, since (due to the fact that all files are opened in binary mode (in order to please Windows), as it was explained here above) they work perfect for the same said relatively large data size ( 10 MB ) when some other program, which uses the same input and output routines based on fread() nor write(), processes the data (in addition to the fact, stated here above, that they work perfect for said relatively small size of data).
 Furthermore, malloc() does not report any error (In addition, I have studied Microsoft documentation about malloc(), and there is no any indication in it why my use of malloc() would not work), its error handling function does not report any error, and the program proceeds to numerical processing, where all variables are used in the most fundamental way ( for example:

a[t][j].real = b[k][l].real + c[m][n].real ;  
a[t][j].imag = b[k][l].imag + c[m][n].imag ;
 
(Of course there is the corresponding “typedef struct complex”, etc., before that, where said arrays of complex variables are defined and allocated. I repeat, this works perfectly for relatively small data, and world perfectly for any data under UNIX)). Looks like there is some mysterious stack overflow or the like event under Windows / Cygwin, but the program does not crash, it executes forever, so there is no any coredump file.


 
 
It seems you've been able to reach the end of my patience ... Congratulations ! Very few have achieved that !

I wish you, and whoever is still willing to try to help you, good luck. But it'll be without me.
tfvg,

Unlike Infinity08, I have infinite patience.

I wrote:
>> Post the code. It will be very interesting to see good code fail in Windows under XP and Cygwin.
and I see that you posted some code.
    a[t][j].real = b[k][l].real + c[m][n].real ;  
    a[t][j].imag = b[k][l].imag + c[m][n].imag ;

Now, I guess I should qualify what I meant by posting the code. I meant that you should post a small program that fails in some capacity under Windows XP or Cygwin.

Why haven't you done this? We said we cannot help you based on the information provided thus far. We believe we can help you if you post a program. If you don't post a program so that we can see the problem you are experiencing, then I have recommended that this question be deleted since it has no value in the PAQ.

Since there may be input/output involved in your small program, then please upload into EE, the small file that you use for processing. For the large 10MB file that gives you problems, you can use http://www.mediafire.com/ to upload files up to 200MB for free users.

Why haven't you posted your small program?
1. Unfortunately, without the code I could just keep trying to guess why the port to XP and Cygwin fails; but I no longer feel this is an effective way to solve this problem.
2. IP is important; however, you could likely find the essense of the porting problem and remove all IP aspects of your code (as has been suggested).
3. If no further Experts try to assist, then the value of this Question for the PAQ is, IMO, useless; therefore, I have no objection to deleting the question.
Avatar of tfvg

ASKER


   If you insist so wildly, the fact, that Windows requires that the files are opened in binary mode in order fread() and fwrite() to function properly, proved that said malfunctioning of said programs is due to malfunctioning of Windows, since said fact constitutes a malfunctioning of Windows. Microsoft had/has a duty to provide a fair warning about said problem, which Microsoft failed. Furthermore, since there was/is a reasonable expectation that an operating system does not require said requirement, Microsoft also failed to maintain reasonable standards of due care in this case. It can be also concluded that Microsoft engaged in unfair business practice in this case, and that it is liable for fraud and deceit, and that it violated statutory rights of the users o Windows, etc..
  Therefore, deleting this discussion would serve the purpose of concealing said wrongdoings of Microsoft Corporation, and would alsol constitute a conspiracy for said purpose


My recommendation is to delete this question as it serves no useful value to the PAQ.
Avatar of tfvg

ASKER


  On the contrary, this discussion did/does serve its purpose, since it revealed that the aforementioned malfunctioning of the aforementioned programs is due to malfunctioning of Windows, as it was proved here above. Furthermore, deleting this discussion would be a wrongdoing, as it was explained in my previous comment.

The basic facts are these:

Known experts in the field have told you that there must be problems in your code

You refuse to prove otherwise by posting your code

You of course have a right to express your opinion and keeping the code to yourself is your prerogative but that does not get us any closer to a solution and makes this thread pretty useless.
tfvg,

You are not being asked to provide proprietary code, you are being asked to provide a small example of something that does not work so the experts can see and understand what your issue actually is and to try and ascertain more specifically why you are seeing apparent incorrect behavior. Do you really consider that an unreasonable request?

So, let's explore why your logic is flawed in your assumption that fread and fwrite should just work on Windows on a file generated on a different platform. Since you refuse to provide an example I will do so instead. This may or may not match your specific problem but that doesn't really matter since its purpose is just to provide an example so as to try and get you to see how a perfectly well formed program can actually be non-portable.

Let's look at some code...

#include <stdio.h>

struct foo
{
   char c;
   int i;
};

// ON UNIX
void unix_write ()
{
   foo fooarray[100];

   // some code to populate the array.

   FILE * fp = fopen("myfile.bin", "wb");
   fwrite(fooarray, sizeof(fooarray), 1, fp);
}

// ON WINDOWS
void windows_read ()
{

   foo fooarray[100];

   FILE * fp = fopen("myfile.bin", "rb");
   fread(fooarray, sizeof(fooarray), 1, fp);
}

Open in new window


What you have here is a perfectly well formed completely correct ANSII compliant code snippet. It's also completely non-portable and in no way is guaranteed to work in so far as generating data on one platform and reading it on another. Why? The reason is because of the data structures you are persisting and the very fact you are using fread/fwrite. Whenever you create a binary file on one platform it is not guaranteed to be readable on another. Nonsense I can already hear you scream at me. Ok, I'll prove it.

When an instance of foo is created how big is it? 5 bytes? 9 bytes? 8 bytes? The answer is we have absolutely no idea as it is platform/compiler specific. To ensure word alignment the compiler is at liberty to add padding as it sees fit. This means foo is not a portable data structure. Likewise, fooarray is not portable either. when you use fwrite to persist the data you are writing everything, all of foo is persisted, including the padding. Now when you read that back on a different platform that implements a different word alignment strategy that padding can only serve to essentially corrupt the data (at least as far as this new platform is concerned).

From the ANSI C Standard: "The padding and alignment of members of structures. This should present no problem unless binary data written by one implementation are read by another."

So, you see just because you are using fread and fwrite gives absolutely no promise or portability. They are just tools it is how you use them that matters. Just like a hammer can be used to either create a masterpiece sculpture or to smash it into little pieces. A hammer is only a useful artist tool in the hands of an artist who knows how to wield it properly. The experts here are artists and they know how to use these tools. They are willing to show you but you are not willing to learn.
>>  it revealed that the aforementioned malfunctioning of the aforementioned programs is due to malfunctioning of Windows

Actually, it's revealed that you don't know as much as you think you do. It's also revealed that you are not prepared to listen to experts who do. It's also shown that you are prepared to slander (actually, since it's in writing that's libel -- good luck if they decide to take action against your unfounded comments) Microsoft rather than admit and accept your own limited knowledge in this respect. There is nothing for Microsoft need disclose because the way their implementation works is completely and totally consistent with the ANSI standard. Rather than babbling on about what you think you know I recommend you obtain a copy of that standard and read it.

http://flash-gordon.me.uk/ansi.c.txt

More specifically, this is ALL the standard says about fread and fwrite and this is all a compiler has to do to comply with this standard:

4.9.8.1 The fread function

Synopsis

         #include <stdio.h>
         size_t fread(void *ptr, size_t size, size_t nmemb,
                  FILE *stream);

Description

   The fread function reads, into the array pointed to by ptr , up to
nmemb members whose size is specified by size , from the stream
pointed to by stream .  The file position indicator for the stream (if
defined) is advanced by the number of characters successfully read.
If an error occurs, the resulting value of the file position indicator
for the stream is indeterminate.  If a partial member is read, its
value is indeterminate.

Returns

   The fread function returns the number of members successfully read,
which may be less than nmemb if a read error or end-of-file is
encountered.  If size or nmemb is zero, fread returns zero and the
contents of the array and the state of the stream remain unchanged.


4.9.8.2 The fwrite function

Synopsis

         #include <stdio.h>
         size_t fwrite(const void *ptr, size_t size, size_t nmemb,
                  FILE *stream);

Description

   The fwrite function writes, from the array pointed to by ptr , up
to nmemb members whose size is specified by size , to the stream
pointed to by stream .  The file position indicator for the stream (if
defined) is advanced by the number of characters successfully written.
If an error occurs, the resulting value of the file position indicator
for the stream is indeterminate.

Returns

   The fwrite function returns the number of members successfully
written, which will be less than nmemb only if a write error is
encountered.

Anything else a compiler does is non-standard. Notice that at no time does the standard mention anything about the format of the data and who it must be written nor that any padding must be removed or any other reformatting must be done to the data to make it portable. There is one simple requirement for these functions, they must read and write the contents of an array to a persisted storage. They do not have to ensure that data can be read back on a different platform.

The simple fact is, your understanding here is wrong. You are basing your arguments on a false premise and there is a danger that if you don't stop and listen you will never learn more than you think you know now. How many more experts do you need to tell you that before you stop and listen? The mind is like a parachute, it only works properly when it is open. Try opening your mind and you might see that every single expert who has posted here has tried to help you. The only person who is wrong and being unhelpful in this thread is you.

I am willing to work with you to get to the bottom of your problems and to teach you what I can so as to ensure you don't get into this position again but to do that I need you to work with me. Are you willing and prepared to do so? If yes then great. If no then I and the other experts will go on our merry way and you can figure how what to do with this thread by yourself.
Avatar of tfvg

ASKER


 The aforementioned programs do not read files which were written on an operating system other than the one where they are executed.  More particularly, the aforementioned programs read files which were written on the same Windows operating system where they are executed. Therefore, the problem of different file formats of the files created on different operating systems is not relevant here.
 When some programs read files which were written on the same operating system where they are executed (of course, all the aforementioned files have the same file format), no any such problems, like the aforementioned, should happen, regardless of whether the files were opened in binary mode.
  Therefore, the fact, that Windows requires that the files are opened in binary mode in order fread() and fwrite() to function properly, proved that said malfunctioning of said programs is due to malfunctioning of Windows, since said fact constitutes a malfunctioning of Windows. Microsoft had/has a duty to provide a fair warning about said problem, which Microsoft failed. Furthermore, since there was/is a reasonable expectation that an operating system does not require said requirement, Microsoft also failed to maintain reasonable standards of due care in this case. It can be also concluded that Microsoft engaged in unfair business practice in this case, and that it is liable for fraud and deceit, and that it violated statutory rights of the users of Windows, etc..

Do you even read what others are writing? More than once it was explained that undefined and unspecified behavior can happen in programs that appear to work perfectly on one platform. You deny or ignore this fact, and turn down any suggested solutions by other experts that can only be based on pure guesses about your code, as you are not willing to take part in a real examination of what might be going on.

Repeating your long, but incorrect reasonings about why the problem is due to malfunctioning of windows and not faulty code over and over again is not helping in any way.
>> the fact, that Windows requires that the files are opened in binary mode in order fread() and fwrite() to function properly, proved that said malfunctioning of said programs

What is the fundemental difference between opening a file in text mode and binary mode? Answer, text mode is for reading text files and binary mode is for reading binary files.

Again, from the ANSI C standard I have already suggested you consult.

A text stream is an ordered sequence of characters composed into
lines , each line consisting of zero or more characters plus a
terminating new-line character.  Whether the last line requires a
terminating new-line character is implementation-defined.  Characters
may have to be added, altered, or deleted on input and output to
conform to differing conventions for representing text in the host
environment.  Thus, there need not be a one-to-one correspondence
between the characters in a stream and those in the external
representation.  Data read in from a text stream will necessarily
compare equal to the data that were earlier written out to that stream
only if: the data consist only of printable characters and the control
characters horizontal tab and new-line; no new-line character is
immediately preceded by space characters; and the last character is a
new-line character
.  Whether space characters that are written out
immediately before a new-line character appear when read in is
implementation-defined.

   A binary stream is an ordered sequence of characters that can
transparently record internal data.  Data read in from a binary stream
shall compare equal to the data that were earlier written out to that
stream, under the same implementation.  Such a stream may, however,
have an implementation-defined number of null characters appended.

Once again I am at pains to point out that there is nothing about the behavior you are seeing that is wrong and that your comments against Microsoft are unfounded and potentially libellous. I have requested a moderator review this thread, specifically, those comments that might hold both yourself and EE in contempt.
OK, I think we've indulged this gentleman enough so I'm going to bow out here. My time is expensive and tfvg's obtuse attitude is bordering on rude.

Have a good weekend everyone.
Avatar of tfvg

ASKER


 The fact is that files do not necessarily have to be opened in binary mode under UNIX in order the aforementioned operating system to be able to handle them with fread() and fwrite() in a proper way. Therefore, claim, that all files must be opened in binary mode in order an operating system to be able to handle them with fread() and fwrite() in any possible case, is obviously false. Based on the above,  requirement, that all files must be opened in binary mode in order some operating system to be able to handle them with fread() and fwrite() in a proper way, is not reasonable to expect. Therefore, Microsoft had/has a duty to provide a fair warning about said problem, which Microsoft failed, etc..


No one ever said files have to be opened in binary mode for being handled in a proper way on windows, and it is simply not true. Text files can without any problems be handled in text mode under windows.
tfvg, read that part of the standard I've highlighted again and read it very very carefully. Try to understand the words, try to comprehend their meaning. If any of those words do not make sense to you (I am mindful of the fact English may not be your native tongue) say and I will endeavour to clarify them.

Put simply, the standard requires that a compiler only read back what was written in text mode if the circumstances it presents are met. That doesn't mean it won't (such as your experience with whatever compiler you are using in Unix) it just means that it doesn't have to. That fact that a compiler may not read back exactly what was written is perfectly acceptable and correct providing this falls within the standards definition of what the compiler can and cannot do. This being the case Microsoft's compiler is completely standards compliant. Why do you think the standard defines the different modes of text and binary?

If you are persisting text open the file in text mode. If you are persisting binary open the file in binary mode. These modes are not interchangeable and attempting to persist binary data to a file opened in text mode will result in undefined behaviour when that data is read back. In other words, you may or may not read back what you wrote. This is how the behaviour is defined by the standard and this is how it is implemented by Microsoft.

The simple fact is Microsoft's compiler is not wrong, you are. If you want to continue thinking otherwise I invite you to post this theory of yours on the newsgroup comp.lang.c (where the people who define the various standards hang out) and tell that that they are all wrong and you are right.

>> Therefore, Microsoft had/has a duty to provide a fair warning about said problem, which Microsoft failed, etc..

Why do they need to warn about something when it behaves exactly as the ANSI C standard prescribes it should? Should a hammer maker warn that you cannot use a hammer to saw wood? Maybe Microsoft should also point out that their compiler cannot be used to make tea? Does that sound like nonsense? It's no more or less nonsense than what you are asserting.

At this point your question has been answered so I do not plan to reply to you any more. Moderator review has been requested regarding your libellous comments regarding Microsoft and if you now attempt to delete this question I will object on the grounds that it has been correctly answered. The fact you do not wish to accept that is really not my problem nor that of the other experts.

I wish you luck with trying to get to the bottom of the issue you have and if/when you are willing to drop the attitude you may post back here and request my (and the other experts) to provide any further clarification should you need it but I will not respond to any further nonsense assertions that you may wish to post and I strongly recommend the other experts follow suit (although that is really up to them if they wish to humour you further).

Avatar of tfvg

ASKER


 The fact is that files do not necessarily have to be opened in binary mode under UNIX in order the aforementioned operating system to be able to handle them with fread() and fwrite() in a proper way. Therefore, claim, that all files must be opened in binary mode in order an operating system to be able to handle them with fread() and fwrite() in any possible case, is obviously false. Based on the above,  requirement that all files must be opened in binary mode in order some operating system to be able to handle them with fread() and fwrite() in a proper way is not reasonable to expect. Therefore, Microsoft had/has a duty to provide a fair warning about said problem, which Microsoft failed, etc..
  In order to prove what is reasonable to expect in some case it is necessary to prove that majority of fair and reasonable observers would expect what is claimed to be reasonable to expect.
In order to estimate the probability that requirement, that all files must be opened in binary mode in order some operating system to be able to handle them with fread() and fwrite() in a proper way, is not reasonable to expect, it would for example suffice to establish how much is C programming language more popular than Pascal programming language ( since C programming language gives more freedom to the programmer than Pascal programming language, at the expense of being more error prone, since Pascal programming language is more stringent, much like Windows is more stringent than UNIX in handling the aforementioned matter, while UNIX gives more freedom to the programmer in handling the aforementioned matter ).
 Today search on Google for the string " c programming" (with quotation marks included) found about 4,360,000 results, while search on Google for the string " pascal programming" (with quotation marks included) found about 127,000 results. Based on this result, C programming language is more than thirty four (34) times more popular than Pascal programming language.    
  Therefore, since the aforementioned result is much more larger than its error margin, based on the above analysis it is safe to conclude that requirement, that all files must be opened in binary mode in order some operating system to be able to handle them with fread() and fwrite() in a proper way is not reasonable to expect.