|
I won't answer each specific question, because as I already said in my previous post, all this is compiler/optimizer specific, and the C++ standard does dictate a single behavior for that...
|
|
|
|
|
I am more interested in which option in MSVC could be used to control such optimization? The string pooling option?
regards,
George
|
|
|
|
|
George_George wrote: I am more interested in which option in MSVC could be used to control such optimization?
Why ?
|
|
|
|
|
Thanks toxcct,
Because I am reading code which pass pointer to string literal allocated in one function, to another function.
I want to know,
1. whether it is safe code?
2. If not, how to make it safe, by turning on string pooling? (I want to save my efforts to rewrite all such code if it is unsafe).
regards,
George
|
|
|
|
|
if you're sticking to MSVC, you can assume it is (as i said in my first post !!)
|
|
|
|
|
Thanks, toxcct!
Good to know you think I am correct this time.
regards,
George
|
|
|
|
|
I think it is always safe (i.e. it maybe unsafe only for not-standard compilers).
Only write access to string literal buffer gives unpredictable results, see, for instance,
[^].
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
|
|
|
|
|
Thanks CPallini,
1.
CPallini wrote: I think it is always safe (i.e. it maybe unsafe only for not-standard compilers).
Do you have any documents support this claim? Even if we turn off string pooling?
2.
I read your referred article, I think it has nothing to do with OLESTR, but dealing with write to const data? Right?
regards,
George
|
|
|
|
|
George_George wrote: Do you have any documents support this claim? Even if we turn off string pooling?
C++ specifications? See below.
George_George wrote: I read your referred article, I think it has nothing to do with OLESTR, but dealing with write to const data? Right?
You're wrong.
First of all OLESTR are string literals [^].
Have you read "Const Storage and String Literals" section, it reports the following excerpt:
The C++ standard (section lex.string) states:
1 A string literal is a sequence of characters (as defined in
_lex.ccon_) surrounded by double quotes, optionally beginning with the
letter L, as in "..." or L"...". A string literal that does not begin
with L is an ordinary string literal, also referred to as a narrow
string literal. An ordinary string literal has type "array of n const
char" and static storage duration [...]
Static storage duration means that memory for literals is allocated when the program begins running and is freed when the program terminates.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
|
|
|
|
|
Thanks CPallini!
Question answered. You are so knowledgable.
regards,
George
|
|
|
|
|
Well, I've Google, after all.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
|
|
|
|
|
Cool, CPallini!
regards,
George
|
|
|
|
|
Perhaps this will help:
#include "stdafx.h"
#include <iostream>
#include <windows.h>
using namespace std;
bool IsOnStack(const void *pData)
{
DWORD StackBase;
DWORD StackLimit;
__asm
{
MOV EAX, DWORD PTR FS:[0x04]
MOV StackBase, EAX
MOV EAX, DWORD PTR FS:[0x08]
MOV StackLimit, EAX
}
DWORD Address = reinterpret_cast<DWORD>(pData);
return (Address >= StackLimit) && (Address < StackBase);
}
const char* PrintStack(const void *pData)
{
return IsOnStack(pData) ? ": Stack" : ": Not on Stack";
}
int main(int argc, char* argv[])
{
const char *pString1 = "String1";
cout << pString1 << PrintStack(pString1) << endl;
char String2[] = "String2";
cout << String2 << PrintStack(String2) << endl;
return 0;
}
Output is:
String1: Not on Stack
String2: Stack
Steve
|
|
|
|
|
Cool, Steve.
MOV EAX, DWORD PTR FS:[0x04]
MOV StackBase, EAX
MOV EAX, DWORD PTR FS:[0x08]
MOV StackLimit, EAX
What is function of FS:[0x04] and FS:[0x08]?
regards,
George
|
|
|
|
|
Do a Google search on the "Thread Information Block" (TIB) or, as it's also known as, the "Thread Environment Block" (TEB).
Steve
|
|
|
|
|
|
|
Thanks Hamid,
I think this link does not relat to my question. My question is whether or not the OLESTR variable is on stack or on heap. Any comments or ideas?
regards,
George
|
|
|
|
|
Oh I think it was my mistake.
|
|
|
|
|
It is ok, Hamid!
At least you have made us to find something new.
regards,
George
|
|
|
|
|
I glad it was al little help for you.
|
|
|
|
|
I have one static library named c.lib, in which there is a global member int gC;
Two other modules, a.exe and b.dll(regular dll using mfc), link to c.lib.
I found that the address of gC is different in a.exe between in b.dll.
Is it strange?
How can I make only one global int gC?(but used both in c.lib, b.dll, and a.exe)
|
|
|
|
|
How you are refering or Declaring the variable gC for a.exe and c.lib ?
|
|
|
|
|
I define int gC in a cpp file in the static library project.
In b.dll and a.exe, when I want to use gC, I use extern int gC ;
|
|
|
|
|
code_discuss wrote: found that the address of gC is different in a.exe between in b.dll.
Is it strange?
No, because the individual modules get their own personal instance of the variable.
Two of the possible solutions are
1) Put the common static library code in a DLL instead.
2) Use conditional compilation to only create the variable in on module (i.e. in the DLL module only)
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|