Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to store string constants that will be accessed by a number of different classes? [closed]

Tags:

c++

c++11

There are too many different answers on stack overflow:

  1. Declare a namespace, and in the hpp file mark all strings as extern const, and in the cpp file put their definitions.

    C++ How to share constants with extern between cpp - Error: storage class specified

  2. Use static const instead of extern const:

    https://softwareengineering.stackexchange.com/questions/351827/is-it-bad-practice-to-define-constants-using-class-static-methods

  3. Use an inline function :

    static string constants in class vs namespace for constants [c++]

  4. Use anonymous namespaces!

    Where do I put constant strings in C++: static class members or anonymous namespaces?

This is all really confusing. Using an inline function seems like a really lengthy and tedious way to return a string constant.

Why can't we just use namespaces containing static strings, which are defined in the cpp file ?

Can someone please provide an categorical / unequivocal answer of how one should store strings in a constant file, so multiple cpp files can access them ?

EDIT: In C# and Java it seems to be a non-issue to store all your constants in a "Constants" file. What is the easiest way to do this in C++ ?

EDIT: These answers in Java seem specific and understandable. In C++ it is unclear which is the way likely to have least compilation time, least memory usage at run time.

Sharing constant strings in Java across many classes?

https://dzone.com/articles/constants-in-java-the-anti-pattern-1

like image 200
Rahul Iyer Avatar asked Oct 28 '25 07:10

Rahul Iyer


1 Answers

This question is way too broad to be answered. But based on further clarifications concerning the nature of the application (names used internally for registering events) given in comments, I would probably suggest something along the lines of using a header like this

#ifndef INCLUDED_EVENT_NAMES
#define INCLUDED_EVENT_NAMES

#pragma once

#include <string_view>

namespace event_names
{
    using namespace std::literals;

    inline constexpr auto name1 = "value1"sv;
    inline constexpr auto name2 = "value2"sv;
}

#endif

Using std::string_view constants rather than plain const char* or const char[N] means that you know the length of each string and don't have to rely on null termination. Using std::string would almost certainly entail memory overhead and initialization cost at runtime. The std::string_views defined here will compile down to code that's directly referring to statically-allocated string literal objects. Even when the same constant is used in multiple translation units (.cpp files) modern compilers will almost certainly store the same string literal in the binary only once (a standard optimization enabled by [lex.string]/15)

If you're stuck with C++11, then it's simplest (and most likely sufficient for what you need to do) to just make some named references for the string literal objects you need:

#ifndef INCLUDED_EVENT_NAMES
#define INCLUDED_EVENT_NAMES

#pragma once

namespace event_names
{
    constexpr auto& name1 = "value1";
    constexpr auto& name2 = "value2";
}

#endif

Since references are not objects, it is impossible for anyone to do anything (accidentally or otherwise) that would cause an actual object to be created for the constant itself (except for the string literal object of course). Also, since it's a reference, it will carry the information about the size of the array, in case anything may be able to take advantage of that (be aware that that size includes the terminating null). And since there still is the implicit conversion to const char* you will be able to use these whereever a plain old C-string is required.

like image 184
Michael Kenzel Avatar answered Oct 31 '25 08:10

Michael Kenzel



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!