|
George_George wrote: When we use OLESTR to allocate a variable from string literal, like OLESTR("Hello World"), the memory space for the string literal is on stack, right?
Nope, String literals don't follow the lifetime rules of the variables allocated on the stack. AFAIK they are always allocated on read-only memory.
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,
So, we can feel free to pass the OLESTR pointer, which points to an OLESTR allocated in one function to another function (I mean passing the address of OLESTR string literal)?
regards,
George
|
|
|
|
|
Yes.
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!
Question answered.
BTW: do you have any support document which declares OLESTR string literal is in global read-only memory other than stack memory?
regards,
George
|
|
|
|
|
technically, yes, with your VC compiler. however, you should know that it's only because of the optimizer, and some other compilers may not behave identically. so I'd say not to make such assumptions then...
|
|
|
|
|
Thanks toxcct,
1.
Do you mean when we enable string pooling, OLESTR string literal will be in global read-only memory, and it is safe to pass from one OLESTR pointer pointed to string allocated in one function to another function.
2.
If we do not enable string pooling, OLESTR string will be in stack, and above operation is not safe?
3.
You always treat OLESTR in stack? Other than in global accessible memory area?
regards,
George
|
|
|
|
|
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.
|
|
|
|