I understand that, if the constant is in an anonymous namespace, 'static' is implied, so we prefer not to add 'static' in that case (please confirm this).
// What about this case?const char* kFruits = {"apple","banana"};
Note that the latter case isn't "technically" const - it's a non-const array of const char*. I could add another const, but that would violate the "do not go crazy with const" rule:
Your declaration is missing either a * or a []. Assuming you declare asconst char* kFruits[] = { ... };
I'm going to bow out on the main question because I'm not certain.On Thu, Nov 15, 2012 at 10:10 AM, Lambros Lambrou <lambros...@chromium.org> wrote:
I understand that, if the constant is in an anonymous namespace, 'static' is implied, so we prefer not to add 'static' in that case (please confirm this).File-scope "static" and an anonymous namespace are similar (in that they prevent a variable from being accessed outside the file) but not identical (in that static produces internal linkage while the namespace still results in external linkage). There are esoteric consequences of this, like the fact that you can use the latter in template arguments but not the former, or that a debugger may be less confused with one or the other. For most purposes, the distinctions don't really matter. Generally people who prefer anonymous namespaces prefer them because "static" means too many things already and thus namespaces are less ambiguous; namespaces are already used for scoping in cases where they have names, so using unnamed ones is consistent; and putting "static" over and over on everything is verbose.
It used to be true that the standard officially deprecated the use of "static" for internal linkage, in favor of anonymous namespaces. However, that has been reversed (see http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1012 ).For constants specifically, in C++ (but not C), declaring a file-scope object as const gives it internal linkage by default, so it technically doesn't need to be "static" or in an anonymous namespace. We don't generally make use of this because most people don't know it.My recommendation is to use anonymous namespaces for this sort of thing, and not "static". I think this provides maximum clarity.
// What about this case?const char* kFruits = {"apple","banana"};Note that the latter case isn't "technically" const - it's a non-const array of const char*. I could add another const, but that would violate the "do not go crazy with const" rule:Your declaration is missing either a * or a []. Assuming you declare asconst char* kFruits[] = { ... };and not
const char** kFruits = { ... };I think you're actually fine. I don't think the former allows kFruits to be retargeted to point at another array. The former is how we recommend people declare these sorts of things normally.
PK--
Chromium Developers mailing list: chromi...@chromium.org
View archives, change email options, or unsubscribe:
http://groups.google.com/a/chromium.org/group/chromium-dev
On Thu, Nov 15, 2012 at 10:37 AM, Peter Kasting <pkas...@chromium.org> wrote:
Your declaration is missing either a * or a []. Assuming you declare asconst char* kFruits[] = { ... };and not
const char** kFruits = { ... };I think you're actually fine. I don't think the former allows kFruits to be retargeted to point at another array. The former is how we recommend people declare these sorts of things normally.I actually think there is a difference here. const inside a function scope doesn't internal or external linkage. By default, it has auto storage though so I think this requires the compile actually stuff kFruits onto the stack even though it's const.
PK
So what effect, if any, does adding 'static' have in that case?
Oh, hah...sorry, I misread. Yeah, I agree const char* kFruits[] is const enough. Adding the last one (const char* const kFruits) is overkill IMO.
// Should this be 'static'?const int kThings = 42;
// What about this case?const char* kFruits = {"apple","banana"};
void SomeClass::SomeMethod() {
const TimeDelta kMaxDelay = TimeDelta::FromMilliseconds(100);
if (this->cur_time - this->last_time > kMaxDelay) {
// do stuff
}
}
void SomeClass::SomeMethod() {
static const TimeDelta kMaxDelay = TimeDelta::FromMilliseconds(100);
if (this->cur_time - this->last_time > kMaxDelay) {
// do stuff
}
}
void SomeClass::SomeMethod() {
if (this->cur_time - this->last_time > 100e6) {
}
}
void SomeClass::SomeMethod() {
void** got = __get_got_address();
TimeDelta* __addr_kMaxDelay = got[__GOT_INDEX_OF_kMaxDelay];
bool* __addr_kMaxDelay__init = got[__GOT_INDEX_OF_kMaxDelay__init];
if (*__addr_kMaxDelay_init == false) {
*__addr_kMaxDelay__init = true;
*__addr_kMaxDelay.value_ = 100e6;
}
if (this->cur_time.value_ - this->last_time.value_ > *__addr_kMaxDelay.value_)
{
// do stuff
}
}
--
When working at removing static C++ initializers from the Chromium code, I discovered that function-scope static const objects are a really bad idea because often the compiler will generate *really* bad code for them.
I was not trying to answer the question of whether "static" makes a difference here or not; I was just trying to say that no extra "const" is necessary, or in fact possible, for the array case to be "fully const" -- it's already as const as it can get. (Unless I'm mistaken.)
Actually, no, something like "const char* kFruits[] = { ... }" at file scope-level, still creates a mutable array of pointers in the .data section, and allows the code to assign values to kFruits[0], kFruits[1], etc...If you use "const char* const kFruits[]" instead, the data will be placed in the .rodata section instead, so you won't be able to modify the pointers at runtime (even through a buffer overflow or random memory corruption), at least in theory (in practice, the last page of the .rodata section can still be kept writable by the dynamic linker due to page-alignment constraints).
--
That said, there are cases where you know that your code will only execute in a single thread, and it’s handy to write it using normal (non-thread-safe) statics instead of having to reach for a LazyInstance or something. I object to an outright ban on this form of static initialization.
Because it’s unsafe on Windows, we build with -fno-threadsafe-statics on non-Windows to make it equally unsafe on all platforms.
On Thu, Mar 28, 2013 at 10:28 PM, Mark Mentovai <ma...@chromium.org> wrote:
Because it’s unsafe on Windows, we build with -fno-threadsafe-statics on non-Windows to make it equally unsafe on all platforms.This looks... like a weird idea. I mean: sure we should not use non-POD statics in portable parts of code and it's probably good idea not to rely on the fact that all platforms except Windows have thread-safe statics but why remove the safety net? Mistakes happen, sometimes people don't realize which statics are safe and which are not, etc.
To be clear: It's not just a matter of whether the code itself is multi-threaded or not but also if the code is used on multiple threads. E.g., a "single-threaded" class with statics used on multiple threads has the same problem even if each thread owns a copy of the class. The bug I linked above is an example of that case.
This is another example of why our advice to developers has long been "do not use a class on more than one thread". Using separate instances of the class for different threads may sound like a safe variant of that, but it's clearly not in this case.
Good point; done: http://dev.chromium.org/developers/coding-style/cpp-dos-and-donts#TOC-Static-variables.
On Thu, Mar 28, 2013 at 12:55 PM, Ami Fischman <fisc...@chromium.org> wrote:
Good point; done: http://dev.chromium.org/developers/coding-style/cpp-dos-and-donts#TOC-Static-variables.Maybe this is too obvious to state there, but using a static at all makes your code much more likely to be thread-unsafe. Maybe we should point out that it's best to avoid statics whenever practical.
I'm happy to put a CL together to fix this if we come to an agreement that this is the right thing to do.
I agree wholeheartedly with the tangent. Keeping func-local constants in the func makes code easier to understand and audit.
--
except for POD types that are initialized to compile-time constants
"Before any dynamic initialization takes place" to my mind implies "before any code is run".
Reviving this thread once again with more data.I just did some research with etienneb and we determined that for compound types (arrays, structs, unions, etc.) at function scope, static is required to avoid a copy at runtime.
Encountered just today link error with static const mebers of structures.
Building latest Chromium master on mac.
Sample code, reduced to minimum size:
struct MyStruct {
static const int value1 = 1;
static constexpr int value2 = 2;
};
Aren't you missing a definition for your constants? I.e. a "int MyStruct::value1;" in a .cc file.
an email to chromium-dev+unsubscribe@chromium.org
<mailto:chromium-dev+unsubscrib...@chromium.org>.
--
С уважением,
Александр Яшкин,
разработчик Нашего Браузера
http://staff.yandex-team.ru/a-v-y/