PDA

View Full Version : C: Misery



danbaron
18-06-2011, 10:07
After hours of frustration, I finally made the little program below, because of what I was convinced was a compiler error in a bigger C program I am trying to do.

The output is not what I expected it to be, and that was a relief.

Who doesn't prefer an error to be his own rather than the compiler's?

:o


' code -----------------------------------------------------------------------------------------

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <math.h>

#define eps 1.0e-12

bool lessthaneps(double test)
{
if (abs(test) < eps)
return true;
else return false;
}

int main()
{
double d = 0.9999;

if(lessthaneps(d))
printf("true\n\n");
else
printf("false\n\n");

return 0;
}

' output ---------------------------------------------------------------------------------------

true

Press any key to continue...

ErosOlmi
18-06-2011, 10:18
I'm not a C expert so maybe I'm totally wrong but you have to keep attention that

#define is just a text replacement macro that takes place at pre-processor compile time.
So your "eps" will just be substrituted in your code with "1.0e-12" before compiling.

Maybe it is better to use const instead because const will define a variable (even if constant) and type checking can take place:

const double eps = 1.0e-12;

Ciao
Eros

kryton9
18-06-2011, 16:17
Dan, I played with removing some of the includes. This compiled fine no warnings or errors:


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


#define eps 1.0e-12


bool lessthaneps(double test)
{
if (abs(test) < eps)
return true;
else return false;
}


int main()
{
double d = 0.9999;


if(lessthaneps(d))
printf("true\n\n");
else
printf("false\n\n");


return 0;
}


Using only these two headers, I got 2 warnings about printf. But the program ran fine and gave the correct answer.
#include <stdlib.h>
#include <stdbool.h>

danbaron
18-06-2011, 20:02
Here is what I found, guys.

(There are lots of these little "traps" in C.)

First of all, 0.9999 is not less than 0.000000000001, so the answer should be, "false".

The mistake is in using, "abs".

abs is defined in "stdlib.h".

It is for integer arguments.

Here, the argument is a double.

So abs converts the argument to an integer - it truncates it, and 0.9999 becomes 0.

And therefore, the answer is, "true".

Instead of using abs, I should have used "fabs", which is defined in "math.h", and is for double arguments.

If you substitute fabs for abs in the code, then the correct answer, false, is output.

(There are also two more absolute value functions in math.h, "fabsf", for floats, and, "fabsl", for long doubles (<-- both from the C99 specification).

To me, C can be (maybe, "is") really frustrating.

(The emoticon I want to show here doesn't appear, so, --> :-( .)

John Spikowski
18-06-2011, 20:55
To me, C can be (maybe, "is") really frustrating.

Any investment you make in learning C will pay off in the end. You may want to look at OxygenBasic first. That will help you understand the WinAPI better with less of a learning curve.

danbaron
30-07-2011, 08:55
I make the same mistakes over and over when using C.

I am making a larger program than the one shown below.

I spent hours of frustration trying to find an error in it.

If you're like me, then when you are looking for an error, you can become desperate, you begin to think the language or compiler is crazy.

And, you become tired, so you can't think clearly.

In that case, the only way you find the error is by stumbling upon it, while trying every conceivable possibility.

I finally found it.

The little program below recreates it.

(Of course, as you know, the bigger a program is, the harder it is to find a stupid mistake.)

#include <stdio.h>

#define pos 1;
#define neg -1;

struct thing
{
int a[10];
int sign;
};

void setsign(struct thing* it, int s)
{
it->sign = s;
}

int main()
{
char c;
struct thing this;

setsign(&this, pos);
printf("%u\n", this.sign);
c = getchar();

return 0;
}

' compiler response ----------------------------------------------------------

Building main.obj.
C:\Users\root\Desktop\New C\error\main.c(22): error #2001: Syntax error: expected ')' but found ';'.
C:\Users\root\Desktop\New C\error\main.c(22): error #2061: Illegal statement termination.
*** Error code: 1 ***
Done.

Charles Pegge
30-07-2011, 23:27
The trouble with C is that it makes major symbols look small while lesser symbols are exaggerated in length.

Semicolons also add to the awkward appearance breaking the natural flow of expression.

Oxygen tolerates much of C syntax mainly for the purpose of understanding C headers. But I cannot resist stripping out the semicolons.



uses "oxygen"


dim as string src="

#define pos 1
#define neg -1

struct thing
{
int a[10]
int sign
}

void setsign(thing* it, int s)
{
it.sign = s
}




int main()
{


thing this

setsign (this, pos)
print this.sign

return 0
}
main


"








o2_asm src
if len(o2_error) then
msgbox 0,o2_error
else
o2_exec
end if


Here is the same code again, using a class this time



uses "oxygen"


dim as string src="

#define pos 1
#define neg -1

class thing
{
int a[10]
int sign

method setsign(int s)
{
sign = s
}
}




int main()
{


thing th

th.setsign (pos)
print th.sign

return
}
main


"




o2_asm src
if len(o2_error) then
msgbox 0,o2_error
else
o2_exec
end if



Charles

danbaron
31-07-2011, 05:45
Maybe I should try Oxygen.
Why haven't I?
I don't know.
Maybe I am biased against Basic.
Maybe I don't want to give credit to someone I know.
Maybe I think it can't be mature enough.
Maybe I think there won't be enough documentation.
How can I analyze myself?

The problem with the code I put above, is with semicolons.

You (or I) should not put a semicolon at the end of a macro definition.

I put,


#define pos 1;

Therefore, it substituted, "1;" for "pos", and line 22 results in,


setsign(&this, 1;);

------------------------------

Also, I keep forgetting that now you can define global constants in C.


const int pos = 1;

Charles Pegge
01-08-2011, 05:53
No obligation to try it Dan. Think of Oxygen at the opposite of Lisp: complex syntax and few brackets :)

I think we are getting close to the end of the experimental phase now, and I want to keep the core language as compact as possible but I'm always interested in new programming concepts.

Charles

danbaron
01-08-2011, 06:41
I think that one guy making a language is at a big disadvantage, even if he is Einstein.
I don't like to be asking/complaining about bugs, missing features, lack of documentation, how to perform certain tasks, etc.
I guess that basically, I'm not comfortable with asking questions.
For me, sometimes it is best to just wait.

Dan