0

I am a professional software developer but I'm largely unfamiliar with C++ syntax. I am trying to compare the value at the end of a pointer with a double in an inherited C++ project.

The following bit of code successfully grabs the valueAddress from a text file and prints, for example

|"Primary key value"|123.456|

where the 123.456 is the value of the double at the address in the text file.

...
char DebugString[64];
int valueAddress;
fscanf(inputFile, "%s %d", key, &valueAddress);//inputFile declared elsewhere
printf("|");
printf(database->primaryKey);// Defined elsewhere and not the focus of this question
printf("|");
sprintf_s(DebugString,64,"%g",* ((double *)valueAddress)); 
printf(DebugString);     
printf("|");
...

Why then, can't I access the value using:

if ((double *)valueAddress < -0.5)
{...} 

as I get the error "error C2440: '>' : cannot convert from 'double' to 'double *'"

I also can't do:

if ((double) *valueAddress < -0.5)
{...} 

as I get the error "error C2100: illegal indirection". Creating a variable and trying to assign that doesn't work either.

valueAddress is an integer in a text file, which is the memory address of a double value. So I need to use the int valueAddress as a double pointer. It clearly works when putting the value in the DebugString, so why won't it work in an if statement? How can I get around this?

I'm clearly misunderstanding the syntax here. What have I got wrong?

9
  • 4
    Are you sure this is a C++ project? Looks like straight C to me. Commented Jul 22, 2015 at 11:59
  • 1
    So I need to use the int valueAddress as a double pointer. No, you surely don´t need to use an int as pointer. And did you read the line with DebugString carefully? It´s different from what you´re trying. Commented Jul 22, 2015 at 12:03
  • 4
    @RichardOwens Well, then it´s bad (tm) C++ code. I didn´t count how many wrong things this code sample has, but it´s more than one. Commented Jul 22, 2015 at 12:04
  • 2
    If you read a pointer from a file, how the heck does the file know where a double is supposed to be stored in memory?! This is really fishy... Commented Jul 22, 2015 at 12:25
  • 1
    (double *)valueAddress < -0.5 how can you compare a double pointer with a double? Commented Jul 22, 2015 at 12:40

3 Answers 3

3

Using an int to represent the address of a double stored somewhere and attempting to cast an int to a double* is undefined behaviour in C++.

An int might not even be large enough to hold a pointer address. On a 64 bit system, a 32 bit int is not sufficient.

You might get away with using intptr_t to represent the address, and cast using *(double*)valueAddress. But it's still not well-defined.

I'm willing to be corrected on this point but I think the only realistic choice is an inline assembly solution specific to your platform to effect this conversion. That said, you're only reading data from a text file, and you can do that using perfectly normal C++.

Sign up to request clarification or add additional context in comments.

3 Comments

If one is willing to use inline asm, using a platform- and compiler-specific C++ solution without asm is not that different...
I disagree: compilers can misbehave with UB constructs, but asm, at least, is well-defined.
A "compiler-specific" solution.
2

First off, int is not the correct data type to store a memory address. You really should use intptr_t from <stdint.h>, which is guaranteed to be the correct size.

To reinterpret this value as a double* and dereference for comparison, you would do:

if ( *(double*)valueAddress < -0.5 )

But I am a little concerned about this. Unless that pointer references memory that already belongs to your program, you are not allowed to access it. Doing so will fall in the realm of undefined behaviour.

7 Comments

It references a global in another process that it has permission to access. It wasn't written by me or anyone in my company...but it works.
@RichardOwens On your computer maybe. But I can guarantee you that environments exist where it fails.
This will break on your new fancy 128 bit Solaris 10 box.
@deviantfan I can't rewrite this, but can you point me at a tutorial or a phrase to google that will help me understand what it's getting wrong? I'm lucky that this only has to run on one physical server, but I don't want to pick up bad habits as I add new functionality.
@RichardOwens This sounds a bit dubious to me. If that pointer is in a shared memory segment that has been negotiated between your two processes it would be okay. Bathsheba is trying to tell you that this isn't forward-compatible. It might happen to work only because the bitness of your two programs matches the underlying architecture, but even then it's a stretch. If that memory gets paged out to disk for any reason, I wouldn't expect that your other process is allowed to recall it.
|
1

You need to dereference your pointer

if ( * ( (double * ) valueAddress ) < -0.5)

This first converts to a pointer, then finds the value pointed to.

5 Comments

Did the job! Why does (double *) valueAddress work when printing to a char array?
@RichardOwens Because you still didn´t read the line at all. The code in your comment is not the code that works there. And you shouldn´t ignore the UB warnings, really.
Look closely at your code, there is an asterisk dereferencing the cast pointer in the sprintf_s statement
@ravenspoint Ah, thank you! I thought that was another parameter that was being passed. My first C++ project isn't going too well.
@RichardOwens I understand that you got "thrown" into it, but maybe you should try to make your boss rethink this again. C++ isn´t something to learn while refractoring a crappy old project, the result will be not much better (probably).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.