473,698 Members | 2,503 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Using strtod

Hi experts,
Is the following usage of strtod okay (p is a char pointer):

value = strtod(p, &p);

Is it possible that this would evoke undefined behaviour?
Or should I use a temporary pointer and then assign its value to p?

Thanks

Feb 18 '07 #1
18 2447
coder wrote:
Hi experts,
Is the following usage of strtod okay (p is a char pointer):

value = strtod(p, &p);

Is it possible that this would evoke undefined behaviour?
Or should I use a temporary pointer and then assign its value to p?
You are allowed to do this as long as you bypass any possible macro
definition of strtod:

value = (strtod) (p, &p);

But it would be cleaner to just use a temporary.

Feb 18 '07 #2
On Feb 18, 10:47 pm, "Harald van Dijk" <true...@gmail. comwrote:
coder wrote:
<snip>
Thanks for the reply, Harald.
You are allowed to do this as long as you bypass any possible macro
definition of strtod:
value = (strtod) (p, &p);
I didn't get that. Can you please explain a little more?
But it would be cleaner to just use a temporary.

Feb 18 '07 #3
coder wrote:
Hi experts,
Is the following usage of strtod okay (p is a char pointer):

value = strtod(p, &p);

Is it possible that this would evoke undefined behaviour?
Or should I use a temporary pointer and then assign its value to p?
You should use a temporary, not because of undefined
behavior (but see Harald van Dijk's response), but because
you will need the original pointer's value when you check
for errors. After strtod(p, &q), the condition p==q means
strtod() was unable to convert any of the input. If you
write strtod(p, &p) you will be unable to make the test.

--
Eric Sosman
es*****@acm-dot-org.invalid
Feb 18 '07 #4
coder wrote:
On Feb 18, 10:47 pm, "Harald van Dijk" <true...@gmail. comwrote:
coder wrote:
<snip>

Thanks for the reply, Harald.
You are allowed to do this as long as you bypass any possible macro
definition of strtod:
value = (strtod) (p, &p);

I didn't get that. Can you please explain a little more?
strtod(p, &p) both reads from p and writes to p. If you're using a
function, there's no problem, because the reading from p is guaranteed
to take place before any write. If you're using a macro, the macro is
allowed to write to p before reading its original value.

Feb 18 '07 #5
coder wrote:
>
Is the following usage of strtod okay (p is a char pointer):

value = strtod(p, &p);

Is it possible that this would evoke undefined behaviour? Or
should I use a temporary pointer and then assign its value to p?
Why not read the description of the function? Note the
'restrict'. From N869:

7.20.1.3 The strtod, strtof, and strtold functions

Synopsis

[#1]
#include <stdlib.h>
double strtod(const char * restrict nptr,
char ** restrict endptr);
float strtof(const char * restrict nptr,
char ** restrict endptr);
long double strtold(const char * restrict nptr,
char ** restrict endptr);

--
<http://www.cs.auckland .ac.nz/~pgut001/pubs/vista_cost.txt>
<http://www.securityfoc us.com/columnists/423>

"A man who is right every time is not likely to do very much."
-- Francis Crick, co-discover of DNA
"There is nothing more amazing than stupidity in action."
-- Thomas Matthews

Feb 18 '07 #6
CBFalconer wrote:
coder wrote:

Is the following usage of strtod okay (p is a char pointer):

value = strtod(p, &p);

Is it possible that this would evoke undefined behaviour? Or
should I use a temporary pointer and then assign its value to p?

Why not read the description of the function? Note the
'restrict'. From N869:

7.20.1.3 The strtod, strtof, and strtold functions

Synopsis

[#1]
#include <stdlib.h>
double strtod(const char * restrict nptr,
char ** restrict endptr);
float strtof(const char * restrict nptr,
char ** restrict endptr);
long double strtold(const char * restrict nptr,
char ** restrict endptr);
I'm pretty sure restrict is irrelevant here. It means the behaviour's
undefined if you do

char *p;
// ...
strtod((char *) &p, &p);

which could otherwise be defined, but it says nothing about

char *p;
// ...
strtod(p, &p);

Feb 18 '07 #7
On 18 Feb 2007 10:54:18 -0800, "Harald van D?k" <tr*****@gmail. com>
wrote in comp.lang.c:
coder wrote:
On Feb 18, 10:47 pm, "Harald van D?k" <true...@gmail. comwrote:
coder wrote:
<snip>
Thanks for the reply, Harald.
You are allowed to do this as long as you bypass any possible macro
definition of strtod:
value = (strtod) (p, &p);
I didn't get that. Can you please explain a little more?

strtod(p, &p) both reads from p and writes to p. If you're using a
function, there's no problem, because the reading from p is guaranteed
to take place before any write. If you're using a macro, the macro is
allowed to write to p before reading its original value.
Chapter and verse, please.

There is nothing at all in the standard that states that strtod() or
the other related strto... functions do not write to the pointer
addressed by their second argument until after they have finished all
use of the first argument.

You may say that were you to implement such a function, you would not
store the pointer value until you were finished with all other
processing. You may say that there is no need for any reasonable
implementation of strtod() to do so.

But unless you can point to wording in the standard that states this,
your answer is wrong and the OP's code produces undefined behavior.

There is absolutely nothing at all preventing an implementation from
providing a strtod() function like this:

double strtod(const char * restrict nptr, char ** restrict endptr)
{
double result = 0.0;
*endptr = NULL;

while (*nptr++ != '\0')
{
/* processing */
}
*endptr = nptr;
}

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.l earn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Feb 19 '07 #8
In article <5s************ *************** *****@4ax.com>,
Jack Klein <ja*******@spam cop.netwrote:
>On 18 Feb 2007 10:54:18 -0800, "Harald van D?k" <tr*****@gmail. com>
wrote in comp.lang.c:
>strtod(p, &p) both reads from p and writes to p. If you're using a
function, there's no problem, because the reading from p is guaranteed
to take place before any write.
>Chapter and verse, please.
There is a sequence point after evaluation of the arguments
to a function, but before the function is called. Copies of the
value of the arguments are passed, not pass by reference.

Therefore, strtod(p,&p) would have to read p and calculate the
address of p, saving the read value and the address (reading
and saving done in any order); then the sequence point
requirement requires that the read and address calculation be
completed and the copies fully saved before the function is
invoked. The function would receive a value in the first
parameter that -happened- to contain the same contents as
could be found by dereferencing the pointer in the second
argument at that time, but there would be no way for the
function body to write into the pointer before that value-
copy had been taken because of the sequence point.

But as Harald pointed out, the sequence point requirements do
not apply to macros, so implementing as a macro could have different
results.
--
"No one has the right to destroy another person's belief by
demanding empirical evidence." -- Ann Landers
Feb 19 '07 #9
You are allowed to do this as long as you bypass any possible macro
definition of strtod:
value = (strtod) (p, &p);

I didn't get that. Can you please explain a little more?

strtod(p, &p) both reads from p and writes to p. If you're using a
function, there's no problem, because the reading from p is guaranteed
to take place before any write. If you're using a macro, the macro is
allowed to write to p before reading its original value.

Chapter and verse, please.

There is nothing at all in the standard that states that strtod() or
the other related strto... functions do not write to the pointer
addressed by their second argument until after they have finished all
use of the first argument.
C uses pass by value. If you pass the value of p as the first
argument and the address of p as the second argument, these values
are determined at the sequence point after argument evaluation but
before the call of the function. The value of the first argument
(pointer) cannot be changed by subsequent alteration of the pointer
pointed at by the second argument.

strtod() may read the value of the string pointed at by its first
argument. strtod() may modify the pointer pointed at by its second
argument, but it is not supposed to read the string originally
pointed at by the character pointer pointed at by the second argument.
(You're allowed to pass &p for an uninitialized pointer p). Since
there is no overlap between what's read through the first argument
and what's read or written through the second, there's no problem.
>You may say that were you to implement such a function, you would not
store the pointer value until you were finished with all other
processing. You may say that there is no need for any reasonable
implementati on of strtod() to do so.
It may do so, and it doesn't matter.
>But unless you can point to wording in the standard that states this,
your answer is wrong and the OP's code produces undefined behavior.

There is absolutely nothing at all preventing an implementation from
providing a strtod() function like this:

double strtod(const char * restrict nptr, char ** restrict endptr)
{
double result = 0.0;
*endptr = NULL;
The above statement cannot mess up nptr nor what it points at.
>
while (*nptr++ != '\0')
{
/* processing */
}
*endptr = nptr;
}
Feb 19 '07 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
3018
by: Mathieu Malaterre | last post by:
Hello, I would like to have some advices on this problem I am having. In my code I have hardcoded a string like: const char foo = "11 0.438482 "; I was then calling strtod to transform it back to double. Unfortunately depending on the LOCALE settings, the strtod could fail.
21
2271
by: Marky C | last post by:
atof is not working. double a = atof("12.345"); a gets set to 12.000 I am working on a toshiba micro. The data map has no space allocated to it for dynamic memory. Does anyone have an idea? Could it be due to the lack of dynamic
9
1966
by: Adam Warner | last post by:
Hi all, Message ID <c1qo3f0tro@enews2.newsguy.com> is one of many informative articles by Chris Torek about C. The particular message discusses aliasing and concludes with this paragraph: Under these strict type-aliasing rules, casting from (e.g.) "int *" to "short *" is not only quite suspicious, it is also likely to cause puzzling behavior, at least if you expect your "short *" to access or modify your "int". Even the time-honored,...
4
2465
by: Gary Wessle | last post by:
Hi I have a vector<stringwhich holds numbers, I need to loop and printout those numbers + a value as doubles . typedef vector<string>::const_iterator vs_itr; for(vs_itr i=vect.begin(); i!=vect.end(); ++i){ cout << *i << '\t' << strtod(*i)+val << '\n';
8
3488
by: Bill Cunningham | last post by:
Since I've been told that char *argv or char **argv must be the second parameter to main's command line structure I have turned to strtod( ) but can't get it to work so far. This function is probably used alot but I obviously am not using it right. #include <stdio.h> int main(int argc, char **argv) { if (argc != 3) {
4
1628
by: Bob Nelson | last post by:
Fellow C pushers: Deliberately avoiding a look at Jack Klein's bulletproof code for a robust use of strtol(), I respectfully submit the following for review and vigorous critique, desiring unapologetic pedantry (in the *very* best sense of that word). In the way of background, I may as well be a C newbie since the nature of my job has not involved day to day use of the language for maybe a decade. Although I am entering my ``golden...
0
9169
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9030
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
8899
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8871
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
7738
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
5861
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4622
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3052
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
2007
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.