Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: Help with going from 32 bit to 64 bit


This question is answered. Helpful answers available: 2. Correct answers available: 1.


Permlink Replies: 13 - Last Post: Dec 17, 2017 9:23 AM Last Post By: Tom Roberts
Tom Roberts

Posts: 102
Registered: 6/21/05
Help with going from 32 bit to 64 bit  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 11, 2017 2:41 AM
Hi, I'm using rad studio 10.2 Tokyo. I tried compiling my windows app as 64 bit today (it compiles fine as 32 bit) and received a string of errors / warnings. Of those that were easily resolved I was wondering why they happened in the first place. Is the 64 bit compiler based on a later version of C++?

Some errors I haven't a clue how to resolve.

I have a TToken class that contains a friend function called Expand. No problem in 32 bit compile but in 64 bit compile I get the error 'use of undeclared identifier Expand' everywhere it appears.

The sqlite3.c amalgamation file is included in my app. There are two sqlite3 private functions called sqlite3GetToken and sqlite3KeywordCode which I've exposed by removing SQLITE_PRIVATE from their code and adding their declarations to the sqlite3.h file. Again no problems compiling in 32 bit but in 64 bit I get the error 'no matching function ...' everywhere they're used outside of the sqlite3.c file itself.

I also get either 'no matching function' or "no member named 'max' in namespace 'std'" when I try to use std::min or std::max.

Can anyone help?
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Help with going from 32 bit to 64 bit [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 11, 2017 11:05 AM   in response to: Tom Roberts in response to: Tom Roberts
Tom Roberts wrote:

Hi, I'm using rad studio 10.2 Tokyo. I tried compiling my windows app
as 64 bit today (it compiles fine as 32 bit) and received a string of
errors / warnings.

Such as?

Did you read the 64bit migration documentation?

https://www.embarcadero.com/rad-in-action/migration-upgrade-center

Of those that were easily resolved I was wondering why they happened
in the first place.

Obviously, your 32bit code is not compatible with the 64bit compiler.
Hard to say more than that without seeing the actual code that is
failing.

Is the 64 bit compiler based on a later version of C++?

The 64bit compiler is Clang-based and supports C++11. Which 32bit
compiler are you using? The classic Borland 32bit compiler is not
Clang-based and does not support C++11. The newer Clang-based 32bit
compiler does.

Some errors I haven't a clue how to resolve.

Such as?

I have a TToken class that contains a friend function called Expand.
No problem in 32 bit compile but in 64 bit compile I get the error
'use of undeclared identifier Expand' everywhere it appears.

Please show the actual code.

The sqlite3.c amalgamation file is included in my app. There are two
sqlite3 private functions called sqlite3GetToken and
sqlite3KeywordCode which I've exposed by removing SQLITE_PRIVATE from
their code and adding their declarations to the sqlite3.h file. Again
no problems compiling in 32 bit but in 64 bit I get the error 'no
matching function ...' everywhere they're used outside of the
sqlite3.c file itself.

Again, please show the actual code.

I also get either 'no matching function' or "no member named 'max' in
namespace 'std'" when I try to use std::min or std::max.

Does the code have an #include <algorithm> statement?

Can anyone help?

Not without more specific details about your code.

--
Remy Lebeau (TeamB)

Tom Roberts

Posts: 102
Registered: 6/21/05
Re: Help with going from 32 bit to 64 bit [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 12, 2017 7:23 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Hi Remy, my apologies. Here's a sample of the other warning/error messages.

'&&' within '||'
operator '?:' has lower precedence than '+'; '+' will be evaluated first
conversion from string literal to 'char *' is deprecated
non-constant-expression cannot be narrowed from type 'int' to 'bool' in initializer list

I didn't see the point of listing them in my opening post as I knew how to resolve them. I presumed I was using clang's 32 and 64 bit compilers and assumed the 64 bit one was based on a later c++ standard. From what you say I'm no longer sure if the 32 bit compiler is clang but I don't recall changing any defaults when installing rad studio tokyo.

I've discovered most of the 'no matching function' errors came about as a result of the 64 bits stronger typing (e.g the 32 bit would happily send a char * to a function expecting an unsigned char * parameter whereas the 64 bit wouldn't). I think the min/max errors were the result of conflicting types of parameters (the result of different size types in 64bit) apart from one which was resolved by including <algorithm> (I'm mystified as to how the latter case compiled OK in 32 bits).

All that remains now is the friend function. Not sure why this works in 32 bit but not 64.

Parse.h contains

class TToken
{
private:
// stuff here
public:
friend String Expand(String &SQL);
};

Parse.cpp contains the implementation of Expand

String Expand(String &SQL)
{
// code here
}

// NB Expand isn't mentioned anywhere else within Parse.cpp

Test64.cpp contains

#include "Test64.h"
#include "Parse.h"
void fct(void)
{
String SQL="";
Expand(SQL);
}

Building Test64.cpp results in

[bcc64 Error] Test64.cpp(7): use of undeclared identifier 'Expand'

Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Help with going from 32 bit to 64 bit [Edit] [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 12, 2017 10:23 AM   in response to: Tom Roberts in response to: Tom Roberts
Tom Roberts wrote:

'&&' within '||'

Never seen that one before. What does the statement actually look like?

operator '?:' has lower precedence than '+'; '+' will be evaluated
first

http://en.cppreference.com/w/cpp/language/operator_precedence

The '+' operator does indeed have a higher precedence than the '?:'
operator. Depending on what the statement aftually looks like, you
probably need to wrap the operands in parenthesis, eg:

? (...) : (...)

conversion from string literal to 'char *' is deprecated

Embarcadero actually documents that one:

http://docwiki.embarcadero.com/RADStudio/en/Errors_and_Warnings_of_Clang-enhanced_C%2B%2B_Compilers#Conversion_from_string_literal_to_.27char_.2A.27_is_deprecated

In a nutshell, assigning a string literal (a const value) to a
**non-const** char* pointer is deprecated in C++11 onwards. Use a
const pointer instead. Or disable the warning.

non-constant-expression cannot be narrowed from type 'int' to 'bool'
in initializer list

I presumed I was using clang's 32 and 64 bit compilers

If that were the case, you wouldn't be having issues migrating code
from one to the other, since they are basically the same compiler
engine. So you were likely using the legacy Borland 32bit compiler
instead.

and assumed the 64 bit one was based on a later c++ standard.

Compared to the legacy Borland 32bit compiler, yes it does.

From what you say I'm no longer sure if the 32 bit compiler is clang

Look in the project settings. There is an option available in 32bit
targets to freely swith between the two 32bit compilers.

I've discovered most of the 'no matching function' errors came about
as a result of the 64 bits stronger typing (e.g the 32 bit would
happily send a char * to a function expecting an unsigned char *
parameter whereas the 64 bit wouldn't).

Definately something that should not be allowed, since they are
different data types. A pointer of one type cannot be assigned to a
pointer of another type without an explicit type cast.

I think the min/max errors were the result of conflicting types of
parameters (the result of different size types in 64bit)

Doubtful, since one or both of the parameter would likely be promoted
to a larger type to satisfy the call.

apart from one which was resolved by including <algorithm> (I'm
mystified as to how the latter case compiled OK in 32 bits).

You were probably calling the C min/max macros instead of the C++ STL
algorithm functions.

All that remains now is the friend function. Not sure why this works
in 32 bit but not 64.

Expand() is not a member of TToken, and it doesn't take a TToken as a
parameter, so why is it declared as a 'friend' at all?

In any case, the code you showed should not compile in 32bit. If it
is, that is a compiler bug.

Building Test64.cpp results in

[bcc64 Error] Test64.cpp(7): use of undeclared identifier 'Expand'

Correct, because you didn't actually declare Expand() itself in Parse.h
(or anywhere else that is accessible to Test64.cpp), so it is unknown.
It only exists as a local function inside of Parse.cpp.

You mention it only as a 'friend' of TToken, and a friendship
declaration can precede the actual function declaration, but doesn't
actually declare the function itself (unless the function is inline,
which yours is not). so you still need to declare it separately, like
any other function, eg:

String Expand(String &SQL); // <-- here
 
class TToken
{
private:
    // stuff here
public:
    friend String Expand(String &SQL);
};


Or:

class TToken
{
private:
    // stuff here
public:
    friend String Expand(String &SQL);
};
 
String Expand(String &SQL); // <-- here


--
Remy Lebeau (TeamB)
Tom Roberts

Posts: 102
Registered: 6/21/05
Re: Help with going from 32 bit to 64 bit [Edit] [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 13, 2017 1:09 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Thanks for that Remy. It's much appreciated.

The '&&' within '||' warnings are all over the place. From what I can see it applies to any statement that includes both '&&' and '||'. e.g.

bool X, Y, Z, A;
A = X || Y && Z;

Expand() is not a member of TToken, and it doesn't take a TToken as a
parameter, so why is it declared as a 'friend' at all?

Expand has a local TToken variable and needed to access many of the parts of TToken that I wanted to be private. Being able to call Expand with a String argument and get a String value returned seemed to cut out a lot of annoying code. In any case declaring it outside of the TToken class as well has indeed solved my problem.

Look in the project settings. There is an option available in 32bit
targets to freely swith between the two 32bit compilers.

The only option I can see is 'Resource Compiler | Resource compiler to use' which gives the choice of brcc32.exe or Windows SDK resource compiler. No mention of clang unless the latter is clang. If it is, does this have to be changed for every project? Is there no way of stipulating a default?
Johannes Weinert

Posts: 90
Registered: 7/19/02
Re: Help with going from 32 bit to 64 bit [Edit] [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 13, 2017 3:55 AM   in response to: Tom Roberts in response to: Tom Roberts
Tom,

Am 13.12.2017 um 10:09 schrieb Tom Roberts:

Look in the project settings. There is an option available in 32bit
targets to freely swith between the two 32bit compilers.

The only option I can see is 'Resource Compiler | Resource compiler
to use' which gives the choice of brcc32.exe or Windows SDK resource
compiler. No mention of clang unless the latter is clang. If it is,
does this have to be changed for every project? Is there no way of
stipulating a default?

the option is called "Use 'classic' Borland compiler" in the category
"Classic Compiler" of the "C++ Compiler" section.

When the option is "true" (which is the default) then the old (classic)
compiler (bcc32) is used. When the option is "false" then the new clang
based compiler (bcc32c) is used.

Regards

Hans
Tom Roberts

Posts: 102
Registered: 6/21/05
Re: Help with going from 32 bit to 64 bit [Edit] [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 13, 2017 4:28 AM   in response to: Johannes Weinert in response to: Johannes Weinert
Johannes Weinert wrote:
the option is called "Use 'classic' Borland compiler" in the category
"Classic Compiler" of the "C++ Compiler" section.

When the option is "true" (which is the default) then the old (classic)
compiler (bcc32) is used. When the option is "false" then the new clang
based compiler (bcc32c) is used.

Regards

Hans

Thanks for the reply Hans but there's no 'Classic Compiler' category in the 'C++ Compiler' section on my Project Options. What version of RAD studio are you using?

Edit. Sorry Hans. I had the target platform at 64 bits. It appeared after I changed to 32 bit. Thanks.

Edited by: Tom Roberts on Dec 13, 2017 4:29 AM
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Help with going from 32 bit to 64 bit [Edit] [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 13, 2017 10:10 AM   in response to: Tom Roberts in response to: Tom Roberts
Tom Roberts wrote:

The '&&' within '||' warnings are all over the place. From what I can
see it applies to any statement that includes both '&&' and '||'. e.g.

bool X, Y, Z, A;
A = X || Y && Z;

You are not using any parenthesis to group operands together. The &&
operator has a higher precedence than the || operator, so such a
statement will be interpretted as "A = X || (Y && Z);", is that what
you really want? Or do you want "A = (X || Y) && Z;" instead? Use
explicit paranthesis to tell the compiler what you really want.

Expand has a local TToken variable and needed to access many of the
parts of TToken that I wanted to be private.

Then TToken should probably have a public Expand() member method that
uses those private members, then your non-member Expand() can call the
member Expand().

--
Remy Lebeau (TeamB)
Tom Roberts

Posts: 102
Registered: 6/21/05
Re: Help with going from 32 bit to 64 bit [Edit] [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 13, 2017 10:52 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Thanks to Remy and Hans I've now got my first 64 bit app up and running. I thought I'd never see the day (I aborted my two previous attempts). I'm surprised there's not been a load of such threads given 'Use classic Borland compiler' is the default for 32 bit.


You are not using any parenthesis to group operands together. The &&
operator has a higher precedence than the || operator, so such a
statement will be interpretted as "A = X || (Y && Z);", is that what
you really want? Or do you want "A = (X || Y) && Z;" instead? Use
explicit paranthesis to tell the compiler what you really want.

It might as well warn me that in the expression A = X + Y * Z I've got * within + OR * within + within =. Definitely one to turn off.


Expand has a local TToken variable and needed to access many of the
parts of TToken that I wanted to be private.

Then TToken should probably have a public Expand() member method that
uses those private members, then your non-member Expand() can call the
member Expand().

Expand is used frequently in code and calling Expand(SQL) saves having to create a TToken first.
Tom Roberts

Posts: 102
Registered: 6/21/05
Re: Help with going from 32 bit to 64 bit [Edit] [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 14, 2017 1:22 AM   in response to: Tom Roberts in response to: Tom Roberts
Tom Roberts wrote:
Thanks to Remy and Hans I've now got my first 64 bit app up and running. I thought I'd never see the day (I aborted my two previous attempts). I'm surprised > there's not been a load of such threads given 'Use classic Borland compiler' is the default for 32 bit.

I spoke too soon there. i had only built the app using the 32 bit clang compiler and assumed it would work in 64 bit but when i tried building it in 64 bit I got 785 linker errors of the form

[ilink64 Error] Error: Public symbol 'SuScript(int, bool)' defined in both module XXX.O and YYY.O

all relating to inline functions declared in .h files like e.g.

WideChar SuScript(int i,bool Subscript=false) {return (Subscript ? 0x2080 : (i==2 || i==3 ? 0x00B0 : 0x2070))+i;}

Example:

Unit1.h

#ifndef Unit1H
#define Unit1H
int Dummy(int i) {return 2*i;}
#endif



File1.cpp

#pragma hdrstop
#pragma argsused

#ifdef _WIN32
#include <tchar.h>
#else
typedef char _TCHAR;
#define _tmain main
#endif

#include <stdio.h>
#include "Unit1.h"

int _tmain(int argc, _TCHAR* argv[])
{
return Dummy(0);
}


Compiles OK in win32 with clang compiler but in win64 gives the following linker errors

[ilink64 Error] Error: Public symbol 'Dummy(int)' defined in both module C:\..\WIN64\DEBUG\FILE1.O and C:\..\WIN64\DEBUG\UNIT1.O
[ilink64 Error] Error: Public symbol 'Dummy(int)' defined in both module C:\..\WIN64\DEBUG\UNIT1.O and C:\..\WIN64\DEBUG\FILE1.O

Any idea what that's about Remy?
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Help with going from 32 bit to 64 bit [Edit] [Edit] [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 14, 2017 10:26 AM   in response to: Tom Roberts in response to: Tom Roberts
Tom Roberts wrote:

i had only built the app using the 32 bit clang compiler and assumed
it would work in 64 bit

It should, since they are both based on Clang.

but when i tried building it in 64 bit I got 785 linker errors of the
form

That is a linker error, not a compiler error.

Compiles OK in win32 with clang compiler but in win64 gives the
following linker errors

[ilink64 Error] Error: Public symbol 'Dummy(int)' defined in both
module C:\..\WIN64\DEBUG\FILE1.O and C:\..\WIN64\DEBUG\UNIT1.O
[ilink64 Error] Error: Public symbol 'Dummy(int)' defined in both
module C:\..\WIN64\DEBUG\UNIT1.O and C:\..\WIN64\DEBUG\FILE1.O

You are not the first person to see that happen:

http://www.bcbjournal.org/forums/viewtopic.php?f=10&t=2507

That error is also mentioned in Embarcadero's documentation (though, it
applies to static data members, not inline functions. But it might be
a related issue):

http://docwiki.embarcadero.com/RADStudio/en/Stricter_C%2B%2B_Compilers_(Clang-enhanced_C%2B%2B_Compilers)

The fix should be easy (albeit probably tedious in your case) - you
probably need to not declare the function as inline in a header file,
but rather move its implementation into the .cpp file so there is only
one copy of it.

--
Remy Lebeau (TeamB)
Tom Roberts

Posts: 102
Registered: 6/21/05
Re: Help with going from 32 bit to 64 bit [Edit] [Edit] [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 14, 2017 11:43 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
The fix should be easy (albeit probably tedious in your case) - you
probably need to not declare the function as inline in a header file,
but rather move its implementation into the .cpp file so there is only
one copy of it.

I was afraid you were going to say that Remy. Thankfully inline fcts within class declarations aren't affected. To alleviate the tedium of dealing with the rest I thought I might try a macro

#define INLINE(x, y) x; x y

such that

INLINE( int Dummy(int i), {return 2*i;} )

would be replaced by

int Dummy(int i); inline int Dummy(int i) {return 2*i;}

In most cases (i.e. where fct params don't have default values) this involved little more than bracketing the existing code, separating the declaration and the body with a comma and adding INLINE to the start. The 64 bit compiler doesn't seem to have a problem with that (I now have a completely compiled and linked app) but can you think of any reason why I shouldn't do this?
Tom Roberts

Posts: 102
Registered: 6/21/05
Re: Help with going from 32 bit to 64 bit  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 14, 2017 5:56 AM   in response to: Tom Roberts in response to: Tom Roberts
Marked unanswered because of 64 bit compiler problems with inline functions.

Edit. Now fully answered.

Edited by: Tom Roberts on Dec 15, 2017 2:15 AM
Tom Roberts

Posts: 102
Registered: 6/21/05
Re: Help with going from 32 bit to 64 bit  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 16, 2017 10:40 AM   in response to: Tom Roberts in response to: Tom Roberts
Just when I thought it was safe to go into the water ...

UnicodeString S="32 bit 'compiles' OK";

win32 S returns "32 bit 'compiles' OK"

win64 S returns "32 bit \'compiles\' OK"

This automatic backslashing of single quotes is playing havoc with strings I'm sending to sqlite3 functions.

Is there any way of turning this off? Straight off I can't even think of a way to undo this as replacing \' with ' just backslashes the replacement single quote.

Edit: My apologies. The backslashes appear in the IDE mouse over, watches, evaluate/modify etc. when the platform's win64 (they don't if it's win32). The blank returns I encountered in sqlite were down to something totally unrelated and nothing to do with phantom backslashes being passed to sqlite.

Edited by: Tom Roberts on Dec 17, 2017 9:13 AM
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02