-
Problem with strtod
Hi. I have been left some code by a previous design engineer which i need to compile. However when i try to compile the code it is giving the following warning:
error C2371: 'strtod' : redefinition; different basic types
c:\program files\microsoft visual studio\vc98\include\stdlib.h(309) : see declaration of 'strtod'
The code is given below:-
Code:
float strtod(char *s,char *endptr) {
float pow10 = 1.0;
float result = 0.0;
int sign = 0, point = 0;
char c;
int ptr = 0;
if(s)
{
c=s[ptr++];
}
while((c>='0' && c<='9') || c=='+' || c=='-' || c=='.') {
if(c == '-') {
sign = 1;
c = s[ptr++];
}
while((c >= '0' && c <= '9') && point == 0) {
result = 10*result + c - '0';
c = s[ptr++];
}
if (c == '.') {
point = 1;
c = s[ptr++];
}
while((c >= '0' && c <= '9') && point == 1) {
pow10 = pow10*10;
result += (c - '0')/pow10;
c = s[ptr++];
}
if (c == '+') {
c = s[ptr++];
}
}
if (sign == 1)
result = -1*result;
if(endptr)
{
if (ptr) {
ptr--;
*((char *)endptr)=s+ptr;
}
else
*((char *)endptr)=s;
}
return(result);
}
Does anybody have any idea what is wrong? Thanks
-
Well, considering strtod is a standard function that returns a double, re-implementing it as a function that returns float would give that sort of problem.
endptr should also be char **, eliminating the ugly casting about that is done in the bottom bit of the function.
--
Mats
-
Hi tried the above and i am now getting the error message warning C4047: '=' : 'const char ' differs in levels of indirection from 'const char *'
Code:
double strtod(const char *s,char **endptr) {
double pow10 = 1.0;
double result = 0.0;
int sign = 0, point = 0;
char c;
int ptr = 0;
if(s)
{
c=s[ptr++];
}
while((c>='0' && c<='9') || c=='+' || c=='-' || c=='.') {
if(c == '-') {
sign = 1;
c = s[ptr++];
}
while((c >= '0' && c <= '9') && point == 0) {
result = 10*result + c - '0';
c = s[ptr++];
}
if (c == '.') {
point = 1;
c = s[ptr++];
}
while((c >= '0' && c <= '9') && point == 1) {
pow10 = pow10*10;
result += (c - '0')/pow10;
c = s[ptr++];
}
if (c == '+') {
c = s[ptr++];
}
}
if (sign == 1)
result = -1*result;
if(endptr)
{
if (ptr) {
ptr--;
*((const char *)endptr)=s+ptr;
}
else
*((const char *)endptr)=s;
}
return(result);
}
-
Code:
*((const char *)endptr)=s+ptr;
should probably be:
(And likewise on the next line).
If you indicate which line you get that error message on, perhaps it would help.
--
Mats
-
Hi Thanks, i tried that - looks like we are getting somewhere, however, the error now is:-
warning C4090: '=' : different 'const' qualifiers
for both the new lines added (i.e. *endptr=s+ptr; and
*endptr=s;)
Code:
double strtod(const char *s,char **endptr) {
float pow10 = 1.0;
float result = 0.0;
int sign = 0, point = 0;
char c;
int ptr = 0;
if(s)
{
c=s[ptr++];
}
while((c>='0' && c<='9') || c=='+' || c=='-' || c=='.') {
if(c == '-') {
sign = 1;
c = s[ptr++];
}
while((c >= '0' && c <= '9') && point == 0) {
result = 10*result + c - '0';
c = s[ptr++];
}
if (c == '.') {
point = 1;
c = s[ptr++];
}
while((c >= '0' && c <= '9') && point == 1) {
pow10 = pow10*10;
result += (c - '0')/pow10;
c = s[ptr++];
}
if (c == '+') {
c = s[ptr++];
}
}
if (sign == 1)
result = -1*result;
if(endptr)
{
if (ptr) {
ptr--;
*endptr=s+ptr;
}
else
*endptr=s;
}
return(result);
}
-
Actually, I think (cheating and looking at glibc's implementation, which is about 100 times more complex than yours) that you need a cast on the endptr assignment:
Code:
*endptr = (char *)s+ptr;
--
Mats
-
Hi. Thats brilliant, no problems have shown up now for this part of the code. Many Thanks!!
When i try to compile in MPLAB it is bringing up a problem with the string.h file :
It says: >>> Warning 201 "C:\PROGRA~1\PICC\drivers\string.h" Line 88(1,1): Assignment inside relational expresion
this is the code it is referring to:
Code:
/* standard template: char *strcat(char *s1, const char *s2)
appends s2 to s1*/
char *strcat(char *s1, char *s2)
{
char *s;
for (s = s1; *s != '\0'; s++);
while ((*s = *s2) != '\0')
//>line error is pointing at {
s++;
s2++;
}
return(s1);
}
why would it be saying there is a problem with a standard library function?
Thanks!
-
I have managed to get rid of the warning message by disabling warning messages, however, during the build using MPLAB with CCsC compiler it is giving these error messages relating to the code i have just modified :
*** Error 32 "G:\MARL\DESIGN\TISR\2002TISR\24-02\MPLAB IDE PIC Project Files\test2.C" Line 24(21,26): Expecting a , or )
*** Error 43 "G:\MARL\DESIGN\TISR\2002TISR\24-02\MPLAB IDE PIC Project Files\test2.C" Line 24(26,27): Expecting a declaration
*** Error 48 "G:\MARL\DESIGN\TISR\2002TISR\24-02\MPLAB IDE PIC Project Files\test2.C" Line 24(27,28): Expecting a (
*** Error 36 "G:\MARL\DESIGN\TISR\2002TISR\24-02\MPLAB IDE PIC Project Files\test2.C" Line 24(36,42): Expecting a ; or ,
*** Error 43 "G:\MARL\DESIGN\TISR\2002TISR\24-02\MPLAB IDE PIC Project Files\test2.C" Line 24(44,45): Expecting a declaration
*** Error 43 "G:\MARL\DESIGN\TISR\2002TISR\24-02\MPLAB IDE PIC Project Files\test2.C" Line 31(4,6): Expecting a declaration
*** Error 43 "G:\MARL\DESIGN\TISR\2002TISR\24-02\MPLAB IDE PIC Project Files\test2.C" Line 31(6,7): Expecting a declaration
*** Error 48 "G:\MARL\DESIGN\TISR\2002TISR\24-02\MPLAB IDE PIC Project Files\test2.C" Line 31(7,8): Expecting a (
etc etc
Why would it be expecting a "(" or ","
Is there any way to ignor these messages - i just want to get the hex file to blow onto the chip?
Code:
double strtod(const char *s,char **endptr) {
float pow10 = 1.0;
float result = 0.0;
int sign = 0, point = 0;
Any Thoughts?
-
here is the full code incase i am missing any thing?
Code:
#include <16f876.h>
#include <stdlib.h>
#include <math.h>
#use delay (CLOCK = 4000000)
#use RS232 (BAUD = 9600,parity = n, bits = 8, xmit=PIN_c6, rcv = PIN_c7, ERRORS)
#use fixed_io (b_outputs=PIN_B0, PIN_B1, PIN_B2, PIN_B3, PIN_B4, PIN_B7)
#use fixed_io (a_outputs=PIN_A5)
#define RELAY_A PIN_B0
#define RELAY_B PIN_B1
#define INC PIN_B2
#define UD PIN_B3
#define CS PIN_B4
#define A_B_SELECT PIN_B5
#define START_UP PIN_B6
#define BUZZER PIN_B7
#define LED PIN_A5
// Test Limits
#define TARGET_VALUE 0.320
#define VARIANCE1 -0.01
#define VARIANCE2 0.01
double strtod(const char *s,char **endptr) {
float pow10 = 1.0;
float result = 0.0;
int sign = 0, point = 0;
char c;
int ptr = 0;
if(s)
{
c=s[ptr++];
}
while((c>='0' && c<='9') || c=='+' || c=='-' || c=='.') {
if(c == '-') {
sign = 1;
c = s[ptr++];
}
while((c >= '0' && c <= '9') && point == 0) {
result = 10*result + c - '0';
c = s[ptr++];
}
if (c == '.') {
point = 1;
c = s[ptr++];
}
while((c >= '0' && c <= '9') && point == 1) {
pow10 = pow10*10;
result += (c - '0')/pow10;
c = s[ptr++];
}
if (c == '+') {
c = s[ptr++];
}
}
if (sign == 1)
result = -1*result;
if(endptr)
{
if (ptr) {
ptr--;
*endptr = (char *)s+ptr;
//*endptr=s+ptr;
//*((const char *)endptr)=s+ptr;
}
else
*endptr = (char *)s;
//*endptr=s;
//*((const char *)endptr)=s;
}
return(result);
}
void select_relay()
{
output_low (RELAY_A);
output_low (RELAY_B);
if (input(A_B_SELECT))
output_high (RELAY_B);
else
output_high (RELAY_A);
delay_us (10);
}
void set_up_digilux()
{
putc('M');
delay_ms(5);
putc('B');
delay_ms(5);
putc(' ');
delay_ms(5);
putc('2');
delay_ms(5);
putc(13);
delay_ms(10);
}
void increment_intensity()
{
output_high (CS);
output_low (UD);
output_low (INC);
delay_ms (50);
output_high (INC);
delay_ms (50);
output_low (INC);
}
void decrement_intensity()
{
output_high (CS);
output_high (UD);
output_low (inc);
delay_ms (50);
output_high (INC);
delay_ms (50);
output_low (INC);
}
void store_pot_value()
{
output_high (CS);
output_low (INC);
delay_ms (100);
output_low (CS);
}
void main()
{
float result;
char a;
char b;
char incoming[50];
char *ptr2;
char *ptr = 0;
float mantissa;
char error_read;
float measurement;
unsigned int exit_loop =0;
char count;
output_low (RELAY_A);
output_low (RELAY_B);
output_low (BUZZER);
output_low (LED);
do
{
select_relay();
exit_loop = 0;
delay_ms(2000);
delay_ms(2000);
delay_ms(2000);
set_up_digilux();
delay_ms(1000);
do
{
do
{
putc('S');
delay_ms(5);
putc('T');
putc(13);
// delay_ms(5);
a=0;
b=0;
do
{
a=getch();
incoming[b++] = a;
} while (a !=13 & b<40);
error_read = (incoming[19] - 0x30);
}while((incoming[1] != 'S' && incoming [2] != 'T') || bit_set(error_read,0));
ptr2 = incoming + 4;
result = strtod(ptr2,&ptr);
a = (incoming[12] - 0x30) * 10;
a += (incoming[13] - 0x30);
mantissa = pow(10,a);
if (incoming[11] == '-')
result /= mantissa;
else
result *= mantissa;
// read_measurement(measurement);
measurement = 0;
measurement = result - TARGET_VALUE;
if(measurement < VARIANCE1)
increment_intensity();
else if(measurement > VARIANCE2)
decrement_intensity();
else
do
{
delay_ms(40000);
do
{
do
{
putc('S');
delay_ms(5);
putc('T');
putc(13);
// delay_ms(5);
a=0;
b=0;
do
{
a=getch();
incoming[b++] = a;
} while (a !=13 & b<40);
error_read = (incoming[19] - 0x30);
}while((incoming[1] != 'S' && incoming [2] != 'T') || bit_set(error_read,0));
ptr2 = incoming + 4;
result = strtod(ptr2,&ptr);
a = (incoming[12] - 0x30) * 10;
a += (incoming[13] - 0x30);
mantissa = pow(10,a);
if (incoming[11] == '-')
result /= mantissa;
else
result *= mantissa;
measurement = 0;
measurement = result - TARGET_VALUE;
// read_measurement(measurement);
if (measurement < VARIANCE1)
increment_intensity();
else if (measurement > VARIANCE2)
decrement_intensity();
else
exit_loop = true;
if(abs(measurement) > 0.1)
delay_ms(200);
else if (abs(measurement) > 0.05)
delay_ms(500);
else
delay_ms(1000);
}while (!exit_loop);
}while (!exit_loop);
if(abs(measurement) > 0.1)
delay_ms(200);
else if (abs(measurement) > 0.05)
delay_ms(500);
else
delay_ms(1000);
}while (!exit_loop);
exit_loop = 0;
store_pot_value();
count = 0;
do
{
output_high (BUZZER);
delay_ms(25);
output_low (BUZZER);
delay_ms(100);
count = count + 1;
} while (count < 6);
output_high (LED);
do
{
output_low (RELAY_A);
output_low (RELAY_B);
}while (input(START_UP));
}while (!input(START_UP));
}
-
Are you sure you closed your previous function (matched all the curly braces)? It looks as though the compiler is looking for a function call, not a function definition. Edit: Now that you've posted code, that's obviously right out. It doesn't appear to me to have any problems that I can see right off. Edit edit: Surely your compiler doesn't require the old K&R-style function signatures, with just the names in the parentheses and then the types later?
-
What compiler are you using?
Edit....... I see you said above.....
Well I am checking out their site and apparently some of their compilers do in fact use K&R syntax.
Example -> http://www.ccsinfo.com/content.php?page=sxcoverview
-
It is possible that they require K&R syntax, but also possible that the support for double (which may be why it was defined with non-standard syntax).
--
Mats