Skip to content

Remove deprecated score::StringLiteral - #745

Merged
limdor merged 2 commits into
mainfrom
mf_fix_use_string_literal_deprecated
Aug 3, 2026
Merged

Remove deprecated score::StringLiteral#745
limdor merged 2 commits into
mainfrom
mf_fix_use_string_literal_deprecated

Conversation

@crimson11

@crimson11 crimson11 commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Fixed wrong/outdated structural diagrams.

Removed usage of deprecated score::StringLiteral in Runtime.
Replaced with const safecpp::zstring_view on implementation
level. Public/user facing APIs using StringLiteral or char*
have been marked deprecated and overloads taking
safecpp::zstring_view have been introduced.

@limdor limdor left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const char * has multiple problems and I do not think this should be the substitute for StringLiteral.

  • An std::string can be converted implicitly from const char * ending with dynamic memory allocation
  • const char* has the problem that it could be a pointer to characters or a pointer to an array of bytes. char meaning is way too overloaded in the standard
  • The fact that it is a pointer, it can end up in all the issues with pointer decay
  • It has no notion of being null terminated or not

Because of that, my proposal would be to go for better alternatives.

Additional note: I saw that in several places you removed the usage of StringLiteral, but the dependency to the target and the include is still there. If we remove StringLiteral we should remove it completly and also remove the include files. Of course it can happen that we break some code if someone relies on the transitive dependency but imho this is a price the users need to pay if they did not have proper includes.

Comment thread score/mw/com/runtime_configuration.cpp Outdated
constexpr auto kDeprecatedConfigurationPathCommandLineKey = std::string_view{"-service_instance_manifest"};
constexpr auto kConfigurationPathCommandLineKey = std::string_view{"--service_instance_manifest"};

void VerifyNullTermination(const std::int32_t argc, const char* argv[])

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is something that you cannot do. The problem of this is that if it is null terminated, you will find it, but if it is not null terminated, you hit undefined behavior.
In the second case, it could even be that you hit some null character in memory that it is totally unrelated.

@LittleHuba LittleHuba left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use C++ infrastructure. E.g. zstring_view or Arguments helper in baselibs.

@crimson11
crimson11 marked this pull request as draft July 23, 2026 06:53
@crimson11

crimson11 commented Jul 23, 2026

Copy link
Copy Markdown
Contributor Author

OK. I guess, I will close this PR then. The thing is: All the usage of const char* stems from the main() entry-point! I.e. there you get const char*, which are guaranteed to be NULL-terminated.
I don't know, how to fix the "issue" then! We expect the user to hand over the char* he gets from the OS in main(). If you now want me to change the signature from our PUBLIC API, where the user currently hands over these char* from main() ... I can't do it.

@limdor , @LittleHuba : Maybe I'm wrong, but to me it seems, that all your input means/can only solved via changng the PUBLIC interface. I.e. require the user NOT to hand over the char* he gets from OS (cmd-line-args) .... if he then also needs to transform these char* to somethings else what is discussed here ... this might also mean eventually heap-allocation ...?

@limdor

limdor commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Yes, it means breaking public API. But the first step would be to provide a second overload that allows the user to use a container of zstring_view and deprecate the API that uses const char *.
And yes, depending how we do it, it might require allocation at startup for the container, but it can also be an allocation aware type.

@crimson11
crimson11 force-pushed the mf_fix_use_string_literal_deprecated branch from 263c6ca to 9476fed Compare July 24, 2026 14:50
@crimson11
crimson11 marked this pull request as ready for review July 24, 2026 14:51
@crimson11
crimson11 force-pushed the mf_fix_use_string_literal_deprecated branch 4 times, most recently from ee86368 to 0758124 Compare July 27, 2026 09:44

@limdor limdor left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the moment I reviewed all changes in the design folder. I think it would be better to move them in a separate PR becasue how I see them is that none of them is related to an API change, it is just because the puml was wrong.

Then for the API additions, I did not review yet. But I assume we will have to update some puml files.

- Runtime(std::pair<Configuration&&, std::optional<tracing::TracingFilterConfig>&&> configs)
{static} + Initialize() : void
{static} + Initialize(const score::cpp::span<const score::StringLiteral> arguments) : void
{static} + Initialize(const score::cpp::span<const char*> arguments) : void

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this change? This seems to already be wrong in the main branch.
Can you fix this in advance in a separate PR? It should only be one Initialize method

static void Initialize(const runtime::RuntimeConfiguration& runtime_configuration);

__
{static} + Initialize() : void
{static} + Initialize(arguments : score::cpp::span<const score::StringLiteral>) : void
{static} + Initialize(arguments : score::cpp::span<const char*>) : void

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{static} +Initialize() : void
{static} +Initialize(int argc, score::StringLiteral argv) : void
{static} +Initialize(std::string const&) : void
{static} +Initialize(runtime::RuntimeConfiguration&) : void

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we move this changes to a separate PR together with https://github.com/eclipse-score/communication/pull/745/changes#r3656356347? That is not really a change in the API, it is just fixing the puml that was wrong.

-binding_runtimes_ : std::unordered_map<BindingType, std::unique_ptr<IBindingRuntime>>
+{static} Initialize() : void
+{static} Initialize(int argc, score::StringLiteral argv) : void
+{static} Initialize(int argc, const char* argv) : void

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


class "<< Stereotype >>\nglobal function" as GlobalFunction {
+MakeError(code : ComErrc, message : score::StringLiteral) : score::result::Error
+MakeError(code : ComErrc, message : const char*) : score::result::Error

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
+MakeError(code : ComErrc, message : const char*) : score::result::Error
+MakeError(code : ComErrc, message : const std::string_view) : score::result::Error

I believe this should be std::string_view. This is what we have in the implementation

score::result::Error MakeError(const ComErrc code, const std::string_view message = "");

Because this is just fixing the puml, it would be good if we can move it out of this PR, because this is not an API change but fixing a mismatch in the puml.

Another thing about this but it was already there before your change, it seems that this says in the puml that it is a global function but it does not seem to mention the namespace. Not sure how you reflect that in puml, I'm not very familiar with it yet.

@crimson11
crimson11 force-pushed the mf_fix_use_string_literal_deprecated branch from 0758124 to 9667138 Compare July 27, 2026 12:22
@crimson11
crimson11 requested review from LittleHuba and limdor July 27, 2026 16:11

@limdor limdor left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added some additional comments.
In general there are several dependency that are still there that could be removed. If you are removing all instances of StringLiteral (that is what I understood) then there should be no more includes of it in our code base and also no more mention of the string literal Bazel target, however there are still quite some, also in places where you removed them.


class "<< Stereotype >>\nglobal function" as GlobalFunction {
+MakeError(code : ComErrc, message : score::StringLiteral) : score::result::Error
+MakeError(code : ComErrc, message : const std::string_view) : score::result::Error

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The const does not matter a lot here considering that it is just a signature, but there is an inconsistency with score/mw/com/design/skeleton_proxy/skeleton_proxy_binding_model.puml
We should spell it the same way in both places.


virtual score::Result<InstanceIdentifierContainer> ResolveInstanceIDs(const InstanceSpecifier model_name) = 0;
virtual void InitializeRuntime(const std::int32_t argc, score::cpp::span<const score::StringLiteral> argv) = 0;
virtual void InitializeRuntime(const std::int32_t argc, score::cpp::span<const char*> argv) = 0;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
virtual void InitializeRuntime(const std::int32_t argc, score::cpp::span<const char*> argv) = 0;
[[deprecated("Please use InitializeRuntime(cpp::span<safecpp::zstring_view> command_line_arguments) for guaranteed NULL terminated arguments")]]
virtual void InitializeRuntime(const std::int32_t argc, score::cpp::span<const char*> argv) = 0;

If we add the deprecation attribute also in the interface it also serve us as a reminder that this is deprecated.

// Expecting that InitializeRuntime will be called on the mock with the same argc / argv that is passed to
// InitializeRuntime (where argv has been converted to an score::cpp::span
constexpr std::int32_t argc{1U};
score::StringLiteral argv[] = {"some_argument"};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a note to this test mentioning that once the deprecated InitializeRuntime(argc, argv) is removed, the test needs to be removed also. This helps to identify that these char* here are only needed for testing this deprecated API.

// TODO: Once InitializeRuntime(argc, argv) is removed, this test will also be removed
TEST_F(RuntimeMockFixture, InitializeRuntimeDispatchesToMockAfterInjectingMock)

InitializeRuntime(argc, argv);
}

TEST_F(RuntimeMockFixture, InitializeRuntimeWithRuntimeConfigurationDispatchesToMockAfterInjectingMock)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe a test is missing for the new added InitializeRuntime(const cpp::span<safecpp::zstring_view> command_line_arguments)

"qualified_name": "score::mw::com::runtime::InitializeRuntime",
"kind": "function",
"signature": "InitializeRuntime : void (const std::int32_t, score::StringLiteral *)"
"signature": "InitializeRuntime : void (const cpp::span<safecpp::zstring_view>)"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is interesting, I do not get why you need to change it and you do not have to add it. I would expect that if we have both (the new overload and the deprecated API) then you have to add one and keep also the old.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@castler this looks like the API surface checker has issues with overloads.

std::optional<std::string> configuration_path{};
for (std::uint32_t arg_idx = 0U; arg_idx < num_args; arg_idx++)
{
const std::string& command_line_argument_key{

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const std::string& command_line_argument_key{
// TODO: Adapt code that we do not need to call `.data()` and that we do not have to rely on life time extension
const std::string& command_line_argument_key{

std::terminate();
}
return score::cpp::at(command_line_args, static_cast<std::ptrdiff_t>(index_of_configuration_path));
return score::cpp::at(command_line_args, static_cast<std::ptrdiff_t>(index_of_configuration_path)).data();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return score::cpp::at(command_line_args, static_cast<std::ptrdiff_t>(index_of_configuration_path)).data();
// TODO: Adapt code that we do not need to call `.data()` and we can provide zstring_view to a filepath
return score::cpp::at(command_line_args, static_cast<std::ptrdiff_t>(index_of_configuration_path)).data();

std::terminate();
}
return score::cpp::at(command_line_args, static_cast<std::ptrdiff_t>(index_of_configuration_path));
return score::cpp::at(command_line_args, static_cast<std::ptrdiff_t>(index_of_configuration_path)).data();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return score::cpp::at(command_line_args, static_cast<std::ptrdiff_t>(index_of_configuration_path)).data();
// TODO: Adapt code that we do not need to call `.data()` and we can provide zstring_view to a filepath
return score::cpp::at(command_line_args, static_cast<std::ptrdiff_t>(index_of_configuration_path)).data();

{
// Given command line arguments which do not contain a configuration path key
std::vector<score::StringLiteral> arguments = {kDummyApplicationName, kDummyConfigurationPath};
std::vector<const char*> arguments = {kDummyApplicationName, kDummyConfigurationPath};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now most of the adapted tests in this file will call a deprecated function. If we do not fix it right away we will have to do it when we remove the deprecation function or in a separate ticket.
All 3 options are fine for me, but it would make sense to fix them right away to show that the approach works.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refactored the test -> they do not use deprecated APIs anymore.

Comment thread score/mw/com/runtime_test.cpp Outdated
// Given a runtime initialised with the path to a configuration file
auto json_path = get_path("mw_com_config.json");
score::StringLiteral test_args[] = {"dummyname", "-service_instance_manifest", json_path.c_str()};
const char* test_args[] = {"dummyname", "-service_instance_manifest", json_path.c_str()};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, now this test calls a deprecated function.

Updated structural and binding model diagrams
to reflect current code correctly.
@crimson11
crimson11 force-pushed the mf_fix_use_string_literal_deprecated branch from 9667138 to ca3eb0c Compare July 31, 2026 15:18
@crimson11
crimson11 requested a review from limdor July 31, 2026 15:29
Removed usage of deprecated score::StringLiteral in Runtime.
Replaced with const safecpp::zstring_view on implementation
level. Public/user facing APIs using StringLiteral or char*
have been marked deprecated and overloads taking
safecpp::zstring_view have been introduced.
@crimson11
crimson11 force-pushed the mf_fix_use_string_literal_deprecated branch from ca3eb0c to 5874c7c Compare July 31, 2026 18:02
@limdor
limdor added this pull request to the merge queue Aug 3, 2026
Merged via the queue into main with commit 0cd1027 Aug 3, 2026
9 checks passed
@limdor
limdor deleted the mf_fix_use_string_literal_deprecated branch August 3, 2026 07:43
@github-project-automation github-project-automation Bot moved this from Backlog to Done in COM - Communication FT Aug 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

3 participants