Skip to content

Commit 9f1c574

Browse files
committed
ICU-23254 Remove C++ static initialization
1 parent 7ed3f0c commit 9f1c574

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+572
-691
lines changed

.github/workflows/icu4c.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -373,12 +373,12 @@ jobs:
373373
374374
# MacOS with clang
375375
macos-clang:
376-
runs-on: macos-14 # Updated in BRS
376+
runs-on: macos-15 # Updated in BRS
377377
steps:
378378
- uses: actions/checkout@ff7abcd0c3c05ccf6adc123a8cd1fd4fb30fb493 # v4.1.1
379379
- name: ICU4C with clang on MacOS
380380
env:
381-
CPPFLAGS: '-Wall -Wextra -Wextra-semi -Wundef -Wnon-virtual-dtor -Wctad-maybe-unsupported -Werror'
381+
CPPFLAGS: '-Wall -Wextra -Wextra-semi -Wundef -Wnon-virtual-dtor -Wctad-maybe-unsupported -Wglobal-constructors -Wexit-time-destructors -Werror'
382382
run: |
383383
cd icu4c/source;
384384
PYTHON=python3 ./runConfigureICU macOS;

icu4c/source/common/loclikely.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,7 @@ GetRegionFromKey(const char* localeID, std::string_view key, UErrorCode& status)
418418
if (U_SUCCESS(status) && len >= 3 && len <= 6 &&
419419
uprv_isASCIILetter(kw[0]) && uprv_isASCIILetter(kw[1])) {
420420
// Additional Check
421-
static icu::RegionValidateMap valid;
421+
icu::RegionValidateMap valid;
422422
const char region[] = {kw[0], kw[1], '\0'};
423423
if (valid.isSet(region)) {
424424
result.append(uprv_toupper(kw[0]), status);

icu4c/source/extra/scrptrun/scrptrun.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ U_NAMESPACE_BEGIN
2323

2424
const char ScriptRun::fgClassID=0;
2525

26-
UChar32 ScriptRun::pairedChars[] = {
26+
const UChar32 ScriptRun::pairedChars[] = {
2727
0x0028, 0x0029, // ascii paired punctuation
2828
0x003c, 0x003e,
2929
0x005b, 0x005d,
@@ -43,11 +43,7 @@ UChar32 ScriptRun::pairedChars[] = {
4343
0x301a, 0x301b
4444
};
4545

46-
const int32_t ScriptRun::pairedCharCount = UPRV_LENGTHOF(pairedChars);
47-
const int32_t ScriptRun::pairedCharPower = 1 << highBit(pairedCharCount);
48-
const int32_t ScriptRun::pairedCharExtra = pairedCharCount - pairedCharPower;
49-
50-
int8_t ScriptRun::highBit(int32_t value)
46+
static constexpr int8_t highBit(int32_t value)
5147
{
5248
if (value <= 0) {
5349
return -32;
@@ -83,6 +79,10 @@ int8_t ScriptRun::highBit(int32_t value)
8379
return bit;
8480
}
8581

82+
const int32_t ScriptRun::pairedCharCount = UPRV_LENGTHOF(pairedChars);
83+
const int32_t ScriptRun::pairedCharPower = 1 << highBit(pairedCharCount);
84+
const int32_t ScriptRun::pairedCharExtra = pairedCharCount - pairedCharPower;
85+
8686
int32_t ScriptRun::getPairIndex(UChar32 ch)
8787
{
8888
int32_t probe = pairedCharPower;

icu4c/source/extra/scrptrun/scrptrun.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,9 @@ class ScriptRun : public UObject {
8686
ParenStackEntry parenStack[128];
8787
int32_t parenSP;
8888

89-
static int8_t highBit(int32_t value);
9089
static int32_t getPairIndex(UChar32 ch);
9190

92-
static UChar32 pairedChars[];
91+
static const UChar32 pairedChars[];
9392
static const int32_t pairedCharCount;
9493
static const int32_t pairedCharPower;
9594
static const int32_t pairedCharExtra;

icu4c/source/i18n/dtptngen.cpp

Lines changed: 6 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -333,11 +333,9 @@ DateTimePatternGenerator::createEmptyInstance(UErrorCode& status) {
333333
}
334334

335335
DateTimePatternGenerator::DateTimePatternGenerator(UErrorCode &status) :
336-
skipMatcher(nullptr),
337-
fAvailableFormatKeyHash(nullptr),
338-
fDefaultHourFormatChar(0),
339-
internalErrorCode(U_ZERO_ERROR)
336+
UObject()
340337
{
338+
emptyString.getTerminatedBuffer();
341339
fp = new FormatParser();
342340
dtMatcher = new DateTimeMatcher();
343341
distanceInfo = new DistanceInfo();
@@ -348,30 +346,15 @@ DateTimePatternGenerator::DateTimePatternGenerator(UErrorCode &status) :
348346
}
349347

350348
DateTimePatternGenerator::DateTimePatternGenerator(const Locale& locale, UErrorCode &status, UBool skipStdPatterns) :
351-
skipMatcher(nullptr),
352-
fAvailableFormatKeyHash(nullptr),
353-
fDefaultHourFormatChar(0),
354-
internalErrorCode(U_ZERO_ERROR)
349+
DateTimePatternGenerator(status)
355350
{
356-
fp = new FormatParser();
357-
dtMatcher = new DateTimeMatcher();
358-
distanceInfo = new DistanceInfo();
359-
patternMap = new PatternMap();
360-
if (fp == nullptr || dtMatcher == nullptr || distanceInfo == nullptr || patternMap == nullptr) {
361-
internalErrorCode = status = U_MEMORY_ALLOCATION_ERROR;
362-
}
363-
else {
364-
initData(locale, status, skipStdPatterns);
365-
}
351+
initData(locale, status, skipStdPatterns);
366352
}
367353

368354
DateTimePatternGenerator::DateTimePatternGenerator(const DateTimePatternGenerator& other) :
369-
UObject(),
370-
skipMatcher(nullptr),
371-
fAvailableFormatKeyHash(nullptr),
372-
fDefaultHourFormatChar(0),
373-
internalErrorCode(U_ZERO_ERROR)
355+
UObject()
374356
{
357+
emptyString.getTerminatedBuffer();
375358
fp = new FormatParser();
376359
dtMatcher = new DateTimeMatcher();
377360
distanceInfo = new DistanceInfo();
@@ -1406,7 +1389,6 @@ DateTimePatternGenerator::setDateTimeFormat(UDateFormatStyle style, const Unicod
14061389

14071390
const UnicodeString&
14081391
DateTimePatternGenerator::getDateTimeFormat(UDateFormatStyle style, UErrorCode& status) const {
1409-
static const UnicodeString emptyString = UNICODE_STRING_SIMPLE("");
14101392
if (U_FAILURE(status)) {
14111393
return emptyString;
14121394
}

icu4c/source/i18n/smpdtfmt.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@ static const int32_t gFieldRangeBias[] = {
236236
// offset the years within the current millennium down to 1-999
237237
static const int32_t HEBREW_CAL_CUR_MILLENIUM_START_YEAR = 5000;
238238
static const int32_t HEBREW_CAL_CUR_MILLENIUM_END_YEAR = 6000;
239+
static constexpr const char16_t HEBREW_CALENDAR_VALUE[] = u"hebr";
239240

240241
/**
241242
* Maximum range for detecting daylight offset of a time zone when parsed time zone
@@ -1483,8 +1484,7 @@ SimpleDateFormat::subFormat(UnicodeString &appendTo,
14831484
Calendar& cal,
14841485
UErrorCode& status) const
14851486
{
1486-
static const int32_t maxIntCount = 10;
1487-
static const UnicodeString hebr(u"hebr");
1487+
static constexpr int32_t maxIntCount = 10;
14881488

14891489
if (U_FAILURE(status)) {
14901490
return;
@@ -1565,7 +1565,7 @@ SimpleDateFormat::subFormat(UnicodeString &appendTo,
15651565
//AD 12345 12345 45 12345 12345 12345
15661566
case UDAT_YEAR_FIELD:
15671567
case UDAT_YEAR_WOY_FIELD:
1568-
if (fDateOverride.compare(hebr)==0 && value>HEBREW_CAL_CUR_MILLENIUM_START_YEAR && value<HEBREW_CAL_CUR_MILLENIUM_END_YEAR) {
1568+
if (fDateOverride == HEBREW_CALENDAR_VALUE && value>HEBREW_CAL_CUR_MILLENIUM_START_YEAR && value<HEBREW_CAL_CUR_MILLENIUM_END_YEAR) {
15691569
value-=HEBREW_CAL_CUR_MILLENIUM_START_YEAR;
15701570
}
15711571
if(count == 2)
@@ -3055,7 +3055,6 @@ int32_t SimpleDateFormat::subParse(const UnicodeString& text, int32_t& start, ch
30553055
return -start;
30563056
}
30573057
UCalendarDateFields field = fgPatternIndexToCalendarField[patternCharIndex]; // UCAL_FIELD_COUNT if irrelevant
3058-
UnicodeString hebr("hebr", 4, US_INV);
30593058

30603059
if (numericLeapMonthFormatter != nullptr) {
30613060
numericLeapMonthFormatter->setFormats(reinterpret_cast<const Format**>(&currentNumberFormat), 1);
@@ -3223,7 +3222,7 @@ int32_t SimpleDateFormat::subParse(const UnicodeString& text, int32_t& start, ch
32233222
// we made adjustments to place the 2-digit year in the proper
32243223
// century, for parsed strings from "00" to "99". Any other string
32253224
// is treated literally: "2250", "-1", "1", "002".
3226-
if (fDateOverride.compare(hebr)==0 && value < 1000) {
3225+
if (fDateOverride == HEBREW_CALENDAR_VALUE && value < 1000) {
32273226
value += HEBREW_CAL_CUR_MILLENIUM_START_YEAR;
32283227
} else if (text.moveIndex32(start, 2) == pos.getIndex() && !isChineseCalendar
32293228
&& u_isdigit(text.char32At(start))
@@ -3263,7 +3262,7 @@ int32_t SimpleDateFormat::subParse(const UnicodeString& text, int32_t& start, ch
32633262

32643263
case UDAT_YEAR_WOY_FIELD:
32653264
// Comment is the same as for UDAT_Year_FIELDs - look above
3266-
if (fDateOverride.compare(hebr)==0 && value < 1000) {
3265+
if (fDateOverride == HEBREW_CALENDAR_VALUE && value < 1000) {
32673266
value += HEBREW_CAL_CUR_MILLENIUM_START_YEAR;
32683267
} else if (text.moveIndex32(start, 2) == pos.getIndex()
32693268
&& u_isdigit(text.char32At(start))

icu4c/source/i18n/transreg.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,7 @@ TransliteratorRegistry::TransliteratorRegistry(UErrorCode& status) :
542542
variantList.adoptElement(emptyString, status);
543543
}
544544
specDAG.setValueDeleter(uhash_deleteHashtable);
545+
fBogus.setToBogus();
545546
}
546547

547548
TransliteratorRegistry::~TransliteratorRegistry() {
@@ -754,10 +755,11 @@ const UnicodeString& TransliteratorRegistry::getAvailableID(int32_t index) const
754755
return *static_cast<UnicodeString*>(e->key.pointer);
755756
}
756757

757-
// If the code reaches here, the hash table was likely modified during iteration.
758-
// Return an statically initialized empty string due to reference return type.
759-
static UnicodeString empty;
760-
return empty;
758+
// If the code reaches here, the hash table was likely modified during iteration,
759+
// or the requested index is out of bounds.
760+
// Return a bogus string due to reference return type,
761+
// and inability to return a UErrorCode from this API.
762+
return fBogus;
761763
}
762764

763765
StringEnumeration* TransliteratorRegistry::getAvailableIDs() const {

icu4c/source/i18n/transreg.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,8 @@ class TransliteratorRegistry : public UMemory {
455455
*/
456456
Hashtable availableIDs;
457457

458+
UnicodeString fBogus;
459+
458460
TransliteratorRegistry(const TransliteratorRegistry &other); // forbid copying of this class
459461
TransliteratorRegistry &operator=(const TransliteratorRegistry &other); // forbid copying of this class
460462
};

icu4c/source/i18n/udatpg.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ udatpg_getDateTimeFormatForStyle(const UDateTimePatternGenerator *udtpg,
248248
}
249249
// Note: The UnicodeString for the dateTimeFormat string in the DateTimePatternGenerator
250250
// was NUL-terminated what it was set, to avoid doing it here which could re-allocate
251-
// the buffe and affect and cont references to the string or its buffer.
251+
// the buffer and affect const references to the string or its buffer.
252252
return result.getBuffer();
253253
}
254254

icu4c/source/i18n/unicode/dtptngen.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -606,17 +606,17 @@ class U_I18N_API_CLASS DateTimePatternGenerator : public UObject {
606606
UnicodeString fieldDisplayNames[UDATPG_FIELD_COUNT][UDATPG_WIDTH_COUNT];
607607
UnicodeString dateTimeFormat[4];
608608
UnicodeString decimal;
609-
DateTimeMatcher *skipMatcher;
610-
Hashtable *fAvailableFormatKeyHash;
609+
DateTimeMatcher *skipMatcher { };
610+
Hashtable *fAvailableFormatKeyHash { };
611611
UnicodeString emptyString;
612-
char16_t fDefaultHourFormatChar;
612+
char16_t fDefaultHourFormatChar { };
613613

614614
int32_t fAllowedHourFormats[7]; // Actually an array of AllowedHourFormat enum type, ending with UNKNOWN.
615615

616616
// Internal error code used for recording/reporting errors that occur during methods that do not
617617
// have a UErrorCode parameter. For example: the Copy Constructor, or the ::clone() method.
618618
// When this is set to an error the object is in an invalid state.
619-
UErrorCode internalErrorCode;
619+
UErrorCode internalErrorCode { U_ZERO_ERROR };
620620

621621
/* internal flags masks for adjustFieldTypes etc. */
622622
enum {

0 commit comments

Comments
 (0)