<!DOCTYPE article PUBLIC "-//NLM//DTD JATS (Z39.96) Journal Archiving and Interchange DTD v1.0 20120330//EN" "JATS-archivearticle1.dtd">
<article xmlns:xlink="http://www.w3.org/1999/xlink">
  <front>
    <journal-meta />
    <article-meta>
      <title-group>
        <article-title>Continuous Source Code Rejuvenation in Continuous Integration Pipelines</article-title>
      </title-group>
      <contrib-group>
        <contrib contrib-type="author">
          <string-name>Endre Fülöp</string-name>
          <xref ref-type="aff" rid="aff0">0</xref>
          <xref ref-type="aff" rid="aff1">1</xref>
        </contrib>
        <contrib contrib-type="author">
          <string-name>Norbert Pataki</string-name>
          <email>patakino@elte.hu</email>
          <xref ref-type="aff" rid="aff0">0</xref>
          <xref ref-type="aff" rid="aff1">1</xref>
        </contrib>
        <contrib contrib-type="author">
          <string-name>Ábel Szauter</string-name>
          <email>abel.szauter@gmail.com</email>
          <xref ref-type="aff" rid="aff0">0</xref>
          <xref ref-type="aff" rid="aff1">1</xref>
        </contrib>
        <aff id="aff0">
          <label>0</label>
          <institution>Department of Programming Languages and Compilers, Faculty of Informatics, Eötvös Loránd University</institution>
          ,
          <addr-line>Budapest</addr-line>
          ,
          <country country="HU">Hungary</country>
        </aff>
        <aff id="aff1">
          <label>1</label>
          <institution>SQAMIA 2024: Workshop on Software Quality</institution>
          ,
          <addr-line>Analysis, Monitoring, Improvement, and Applications</addr-line>
        </aff>
      </contrib-group>
      <abstract>
        <p>Most programming languages have a rather long history, they evolve time by time. However, code written in older version of a programming language is not updated automatically when a new standard is released. Moreover, the existing code may have diferent meaning according to the new standard in extraordinary cases. A rather hard and important task in software engineering is writing code that is maintable, comprehensible and prepared for long term. Continuous integration methods are quite popular because they increase the code quality, and maintainability as they execute many steps in a pipeline when someone makes a change in the code base. These pipelines typically execute the necessary build steps, evaluate the unit, component, integration and end-to-end test cases. Pipelines may use static analyzers to check conventions and subtle language-oriented problems. In this paper, we propose a new step in continuous integration pipelines which aims at the long-term code maintainability based on source code rejuvenation methods that ensure the utilization of more modern standards of the programming language. We take advantage of the Clang compiler infrastructure for our use cases, however, the approach is not specific to a language or another tool. We design a system of standalone plugins in which every plugin is responsible for a separate rejuvenation method. We analyze what are useful options to execute the transformations. We develop a criteria system, and evaluate these options.</p>
      </abstract>
      <kwd-group>
        <kwd>eol&gt;Continuous Integration</kwd>
        <kwd>Source Code Rejuvenation</kwd>
        <kwd>Clang</kwd>
      </kwd-group>
    </article-meta>
  </front>
  <body>
    <sec id="sec-1">
      <title>1. Introduction</title>
      <p>
        One of the most fundamental questions in software engineering is how to write eficient, bug-free,
maintainable, convenient source code that can be considered for long term. In modern software
engineering, continuous integration (CI) pipelines are utilized often to increase the code quality with
the execution of the test cases, and the source code is evaluated with analyzers regularly [
        <xref ref-type="bibr" rid="ref1">1</xref>
        ]. Typically,
many steps of a comprehensive pipeline are executed when a developer makes a change in the codebase.
CI servers provide rapid feedback if the codebase in the repository does not meet the expectations [
        <xref ref-type="bibr" rid="ref2">2</xref>
        ].
      </p>
      <p>
        Programming languages are also in the focus of improvements. Newer and newer standards are
available, more and more features the programming languages have and the developers are eager to use
these new features [
        <xref ref-type="bibr" rid="ref3">3</xref>
        ]. In static analysis, new kind of methods have been proposed for modernize the
source code called source code rejuvenation [
        <xref ref-type="bibr" rid="ref4">4</xref>
        ]. However, migrating the code base between diferent
standards of a programming language is not that easy because the semantics of the code may change [
        <xref ref-type="bibr" rid="ref5">5</xref>
        ].
Special tools are required for the source code rejuvenation [
        <xref ref-type="bibr" rid="ref6">6</xref>
        ]. For instance, C++’s exception handling
constructs changed significantly, a standalone tool is proposed [
        <xref ref-type="bibr" rid="ref7">7</xref>
        ]. The development of user-defined
iterators is changed drastically in the recent standards of C++, and a tool for rejuvenation is presented
[
        <xref ref-type="bibr" rid="ref8">8</xref>
        ].
      </p>
      <p>However, source code rejuvenation methods are not well-known and only stand-alone solutions
are available. CI servers are utilized, but typically not support rejuvenation, and thus codebases can
become obsolete in the long term. In this paper, we propose an approach which defines a workflow of
rejuvenation in CI pipelines.</p>
      <p>The rest of this paper is organized as follows. Section 2 presents the basic components that are
involved in the this research. Related work is discussed in Section 3. The proposed method is presented
in Section 4. Finally, this paper is concluded in Section 5.</p>
    </sec>
    <sec id="sec-2">
      <title>2. Basic components</title>
      <sec id="sec-2-1">
        <title>2.1. Programming Languages</title>
        <p>
          Many recently used programming languages have a rather long history and during the past years,
many standards are released [
          <xref ref-type="bibr" rid="ref9">9</xref>
          ]. Programming languages extend their set of constructs when a new
standard becomes available [10]. The new constructs make the development easier, make the code more
comprehensible or elegant, or increase the safety [11]. However, some constructs can be specified as
deprecated or not supported anymore [
          <xref ref-type="bibr" rid="ref8">8</xref>
          ]. Moreover, the backward compatibility may have a ungracious
impact on the code quality [12]. The relevance of the history overview is important to understand how
old code snippets can be survived with memory and safety issues. An important aspect of the history is
to check how many subtle standards can be used and how complex the compatibility is.
        </p>
        <p>The Fortran programming language was developed in 1957, therefore it has a long history that can be
seen on Table 1. Many standards have been released during this long history, however, in a few cases,
there was more than years between two consecutive releases [13].</p>
        <p>The C programming language is older than 50 years, its history can be seen on Table 2. C has less
releases compared to Fortran.</p>
        <p>The C++ programming language is based on the C programming language and has a rich history
[14]. The language becomes even bigger regularly, it went through a quite radical modernization since
2011, however, many C code is still valid C++. History of C++ can be seen on Table 3.</p>
        <p>Java has a rather compact history with many standards that can be seen on Table 4. After a rather
big intervals, recently two standards are appeared in a year, so the release of the new standards has
been sped up.</p>
        <p>Backward and forward compatibility is an important aspect in the evolution of standards which mean
the code written according to an older standard should work in the very same way according to the
new standard. Threrefore semantics of existing codebase should not be changed. However, there are
well-known examples in which the compatibility is broken.</p>
        <p>
          The code snippet on Figure 1 has diferent outcome according to C++03 and C++11 [
          <xref ref-type="bibr" rid="ref5">5</xref>
          ].
        </p>
        <p>According to classical C++, the outcome is: 0 0 0 0 0, however, according to modern C++, the
outcome is: 0 1 2 3 4.</p>
      </sec>
      <sec id="sec-2-2">
        <title>2.2. Static Analysis and Souce Code Rejuvenation</title>
        <p>Static analysis is an approach in which one reasons about a program based on the source without
execution of the analyzed code [15]. It can be used for many purposes, for instance, finding or predicting
bugs, refactoring or visualizing the code, or measuring code complexity [16].
std::vector&lt;Foo&gt; v( 5 );
for( int i = 0; i &lt; v.size(); ++i )
{</p>
        <p>std::cout &lt;&lt; v[ i ].x &lt;&lt; ’ ’;</p>
        <p>
          Nowadays, source code rejuvenation tools started to appear since they are enablers to modernize
existing codebases in an automatic or a semi-automatic way. This is a source-to-source transformation
that replaces obsolete languages constructs and approaches with modern code [
          <xref ref-type="bibr" rid="ref4">4</xref>
          ]. These rejuvenation
tools can modify the existing code, so in this sense, they are similar to refactoring tools, however, they
difer in many ways too. For instance, rejuvenation is directed transformation that increases the level
of abstraction, however, refactoring is not directed, and they have diferent indicators as well [
          <xref ref-type="bibr" rid="ref4">4</xref>
          ]. Static
analyzers are used in CI servers to find bugs, but source code rejuvenation tools are typically applied
occasionally. Our aim is the application of code rejuvenation regularly in CI environment.
2.3. Clang
Clang is a comprehensive compiler infrastructure based on LLVM [17]. It contains many useful analyzers
and tools, a C/C++ parser, an API for the further development of new static analyzers tools. The parser
constructs the abstract syntax tree (AST) from the source and this built AST can be processed in a
user-defined way. Clang is a popular solution in research, but many big companies take advantage of
it. In this paper, we analyze how it can be applied for rejuvenation as a plugin system, and how the
validation of the rejuvenation can be executed.
        </p>
      </sec>
      <sec id="sec-2-3">
        <title>2.4. Continuous Integration</title>
        <p>Continuous Integration is a software development methodology that emphasizes the regular merging
of the developers’ work. The source code is maintained in a version control repository and diferent
steps in CI pipeline are executed when a new version becomes available. This approach provides fast
feedback to the developers.</p>
        <p>CI methodology is typically supported with CI servers, like Jenkins or GitLab to name a few [18].
These tools are highly configurable, supported with many plugins for the comprehensive evaluation of
the source code, the system under development, and the test cases [19].</p>
        <p>A typical CI pipeline starts with the compilation and other build processes. After this successful step,
diferent testing methods are launched. Unit testing, component testing, integration testing, end-to-end
testing, UI test also can be executed. Static analyzers try to find diferent kind of bugs, code smells,
checking coding conventions. In case of any problem, developers are notified, and a global dashboard
presents the result.</p>
        <p>Continuous Delivery (CD) extends CI pipelines with deployment features, and DevOps pipelines can
extend the pipeline with operational (e.g. monitoring) features.</p>
      </sec>
    </sec>
    <sec id="sec-3">
      <title>3. Related Work</title>
      <p>In this section, the related work is discussed. It is divided into two groups, the first one belongs to
source code rejuvenation as stand-alone solutions. The second part belongs to the CI’s utilization and
configuration.</p>
      <p>
        The topic of source code rejuvenation methods is recently researched intensively. For instance,
modern way of C++ functors is proposed [20]. Modernization of C++ iterator development is shown
[
        <xref ref-type="bibr" rid="ref8">8</xref>
        ]. Rejuvenation of C++’s exception specification is also implemented [
        <xref ref-type="bibr" rid="ref7">7</xref>
        ]. During the introduction of
source code rejuvenation, the authors present a method for utilizing initializer lists [
        <xref ref-type="bibr" rid="ref4">4</xref>
        ]. However, these
tools are standalone solution, not designed for execution in CI pipelines.
      </p>
      <p>A/B Testing is a method which aims at increased user experience based on the evaluation of two
similar versions of the same software [21]. This solution afects the deployed software at runtime, and
can be executed via CI/CD pipelines [22].</p>
      <p>
        Refactoring in CI is not a straightforward approach, however, a survey has been evaluated to check
whether some developers are eager for it [23]. An automatic bot-like solution has been proposed for
regular refactoring without introduction of CI [24]. However, refactoring and code rejuvenation difer
in many ways [
        <xref ref-type="bibr" rid="ref4">4</xref>
        ].
      </p>
    </sec>
    <sec id="sec-4">
      <title>4. The Proposed Method</title>
      <p>In this section, we present our method. This approach has three major parts, the first one belongs to the
execution of source code rejuvenation, the second one belongs to the validation whether the meaning
of code is unchanged during the rejuvenation, and the third part is pipeline in the CI environment.</p>
      <sec id="sec-4-1">
        <title>4.1. Source Code Rejuvenation</title>
        <p>Clang Tooling API provides a powerful framework for building custom static analysis tools. Still, it
has a limitation: the Clang driver can only load a single shared object simultaneously. This section
describes alternative approaches to running multiple source-code analysis plugins on the analysed
project. These approaches are then evaluated for using these analysis tools in a CI/CD pipeline, detailing
the advantages and disadvantages.</p>
        <p>The workflow involves using the implementations of multiple Clang Tooling plugins sequentially
for a single source file. It assumes that there is no interference in the plugins, i.e., they do not modify
the same files on disk, and there is the assumption that all of these plugins treat the source AST in
a read-only fashion. Consequently, there is also the assumption that the order of execution does not
matter (both in the plugins ran and the source files analyzed). The trivial use-case is that given the
project description, i.e., the list of all compiler invocations that produce the end libraries and binaries,
each tool should be run on each translation unit once.</p>
        <p>The naive approach is the default supported workflow, which means running a Clang invocation for
each plugin and each translation unit (see Figure 2). This is the most documented usage of the tool, and
it requires no modification in the source or binary formats of the plugin or Clang. The downside is that
it requires  times  clang invocations, where  is the number of plugins, and  is the number of
translation units.</p>
        <p>The next option is the implementations of multiple Clang Tooling plugins are merged into a single
shared object, as seen in Figure 3. This shared object is then passed to the Clang driver, which loads it and
executes all the contained plugins in a single run. This approach avoids the overhead of parsing the same
...</p>
        <p>clang ... -load plugin_1.so ... -plugin plugin1
ifle multiple times, which would be necessary if the plugins were run separately. The disadvantage is
that merging the plugin source code requires merging, which may lead to code maintenance challenges.</p>
        <p>In the next option, a custom MultiplexConsumer combines multiple ASTConsumers from diferent
plugins into a single consumer. This allows multiple plugins to be executed in a single Clang run without
merging their implementations, thus simplifying the loading process compared to Approach #1. The
downside is that this requires modifying the plugin source, as the ASTConsumer subclass types must
be extracted and exposed to the proxy plugin implementation.</p>
        <p>In the next option, we modify the plugins to support an extern C API for creating and destroying
instances of the ASTConsumer subclass. The proxy plugin can dynamically load these shared objects
and instantiate the ASTConsumers. This approach requires modifying the plugin source but allows
dynamic plugin loading. The disadvantage is that this requires modifying the source of the plugins to
support instantiating the ASTConsumer subclasses via C-language-linkage functions.</p>
        <p>In next option, we patch Clang to support loading multiple shared object files. This is the most
intrusive change, as it requires deploying a custom Clang binary. However, it allows the most flexibility
in loading plugins, and it does not require modifying the plugins’ source code.</p>
        <p>The comparion and evaluation of the analyzed approaches can be found in Table 5.</p>
      </sec>
      <sec id="sec-4-2">
        <title>4.2. Validation</title>
        <p>Upgrading C++ code from an older standard to a newer one carries the risk of semantic diferences,
which means that compiling and running the upgraded code may yield diferent results. Investigating
these diferences is both necessary and important.</p>
        <p>During the compilation of C++ code, the compiler constructs an Abstract Syntax Tree (AST), which
stores pointers to the parsed statements and expressions. Tools such as clang-tidy allow us to check,
iflter, and even modify the AST. By comparing the ASTs of code compiled with the older and newer
standards, we can identify the main diferences.</p>
        <p>Using clang++, we can generate an AST dump which is the representation of the AST in raw text.
However, comparing these dumps directly can be challenging due to the memory addresses of the
pointers shown in the AST which most of the time are diferent.</p>
        <p>To eficiently work with ASTs, we can use Clang LibTooling, a well-known C++ library that allows
developers to utilize the Clang AST for software development. The LibTooling library provides the
RecursiveASTVisitor class, which facilitates the comparison of two ASTs by allowing us to easily
iterate over the AST nodes using a Depth-First Search (DFS) algorithm.</p>
        <p>Although comparing ASTs using DFS sounds straightforward, there may be diferences that do not
afect the results because they do not involve semantic changes. Over the years, the C++ standard
library has undergone many changes, making it safer and more optimized. While these improvements
should not impact the program’s output, they can alter the AST. Therefore, it is crucial to distinguish
diferences that afect semantics from those that do not.</p>
        <p>To ignore diferences that do not afect the result, we can use other methods besides AST comparison.
Symbolic execution, for instance, allows us to determine the program’s output without running it
by replacing variables with symbolic values. This technique is powerful for program analysis and
verification.</p>
        <p>Another approach is to check for diferences between standards and determine whether a given
statement has changed. The cppreference.com site documents changes between standards, but having a
database with these changes would be more eficient for searching than using the cppreference site
directly.</p>
        <p>There are also tools such as Creduce and Delta Debugging, which run the code with diferent standards
and investigate the diferences.</p>
      </sec>
      <sec id="sec-4-3">
        <title>4.3. Workflow in Continuous Integration Pipelines</title>
        <p>In the workflow, we evolve how to use the proposed methods to ensure continuous rejuvenation in a CI
pipeline.</p>
        <p>The proposed workflow consists of the following steps:
1. Evaluation of code as it is currently available in the repository
2. Execute the source code rejuvenation processes
3. Validate whether the rejuvenation does not break the backward compatibility
4. Request for approvement
5. Evaluation of rejuvenated code
6. The rejuvenated code is commited back to repository</p>
        <p>The pipeline starts with the ordinary validation of the committed code. If no problem is found
the rejuvenation process is executed and checks if there is no compatibility issue. In the pipeline, an
approvement should be required for the responsibility. After the approvement, the rejuvenated code is
evaluated as a usual CI solution. If any step of the pipeline fails, the entire process is stopped and the
problem is reported that can be evaluated. If anything is fine, than the code is committed back which
means the pipeline transaction is committed as well.</p>
        <p>
          The implementation of this pipeline is ongoing. We started to use Jenkins as a CI server because it is
widely-used and comprehensively configurable [
          <xref ref-type="bibr" rid="ref2">2</xref>
          ].
        </p>
      </sec>
    </sec>
    <sec id="sec-5">
      <title>5. Conclusion and Future Work</title>
      <p>In this paper, a rather important question is discussed: how we can write source code that is bug-free,
modern, maintainable. Programming languages have a quite long history, and because of the backward
compatibility, codebases may become old in a bad way. Source code rejuvenation solutions are recently
researched, but the proposed tools are standalone ones. Continuous Integration methods are popular
because of the rapid feedback to developers if something goes wrong in the repository. We propose an
approach in which rejuvenation methods become the part of the CI pipeline. We analyze how to deal
this issue in diferent aspects. We analyze how to integrate the rejuvenation methods, how to validate
them and how CI pipeline can introduce this solution.</p>
      <p>Currently, our approach belongs to the C/C++ realm, we use the Clang compiler infrastructure.
However, the ideas are not specific to a language or a CI tool, but general ones. As a future work, we
should create a generic solution that can be specified for a programming language. Moreover, a general
CI plugin can be implemented for a seamless work.
[10] A. M. Gorelik, Statements, data types and intrinsic procedures in the Fortran standards (1966-2008)
33 (2014). URL: https://doi.org/10.1145/2701654.2701655.
[11] G. Dévai, N. Pataki, Towards verified usage of the C++ Standard Template Library, in: Proceedings
of the 10th Symposium on Programming Languages and Software Tools, SPLST 2007, 2007, pp.
360–371.
[12] A. Sundelin, J. Gonzalez-Huerta, K. Wnuk, The hidden cost of backward compatibility: when
deprecation turns into technical debt - an experience report, Association for Computing Machinery,
New York, NY, USA, 2020. URL: https://doi.org/10.1145/3387906.3388629.
[13] M. Metcalf, J. Reid, M. Cohen, R. Bader, Modern Fortran Explained: Incorporating Fortran 2023,</p>
      <p>Oxford University Press, 2023.
[14] B. Stroustrup, The C++ Programming Language, 4th ed., Addison-Wesley Professional, 2013.
[15] B. Babati, N. Pataki, The role of implementation-specific static analysis, in: 2023 International
Conference on Software and System Engineering (ICoSSE), 2023, pp. 1–6. doi:10.1109/ICoSSE58936.
2023.00009.
[16] J. Malm, E. Enoiu, M. A. Naser, B. Lisper, Z. Porkoláb, S. Eldh, An evaluation of general-purpose
static analysis tools on C/C++ test code, in: 2022 48th Euromicro Conference on Software
Engineering and Advanced Applications (SEAA), 2022, pp. 133–140. doi:10.1109/SEAA56994.
2022.00029.
[17] B. Babati, G. Horváth, V. Májer, N. Pataki, Static analysis toolset with Clang, in: Proceedings of
the 10th International Conference on Applied Informatics, 2017, pp. 23–29. doi:10.14794/ICAI.
10.2017.23.
[18] M. Shahin, M. Ali Babar, L. Zhu, Continuous integration, delivery and deployment: A systematic
review on approaches, tools, challenges and practices, IEEE Access 5 (2017) 3909–3943. doi:10.
1109/ACCESS.2017.2685629.
[19] C. Singh, N. S. Gaba, M. Kaur, B. Kaur, Comparison of diferent CI/CD tools integrated with cloud
platform, in: 2019 9th International Conference on Cloud Computing, Data Science &amp; Engineering
(Confluence), 2019, pp. 7–12. doi: 10.1109/CONFLUENCE.2019.8776985.
[20] G. Horváth, N. Pataki, Transparent functors for the C++ Standard Template Library, in: E. Vatai
(Ed.), Proceedings of the 11th Joint Conference on Mathematics and Computer Science, CEUR-WS,
2016, pp. 96–101.
[21] Á. Révész, N. Pataki, Containerized A/B testing, in: Z. Budimac (Ed.), Proceedings of the Sixth
Workshop on Software Quality Analysis, Monitoring, Improvement, and Applications,
CEURWS.org, 2017, pp. 14:1–14:8. URL: http://ceur-ws.org/Vol-1938/paper-rev.pdf.
[22] Á. Révész, N. Pataki, A/B testing via Continuous Integration and Continuous Delivery, in:
S. Bourennane, P. Kubicek (Eds.), Geoinformatics and Data Analysis, Springer International
Publishing, Cham, 2022, pp. 165–174. doi:10.1007/978-3-031-08017-3_15.
[23] C. Vassallo, F. Palomba, H. C. Gall, Continuous refactoring in CI: A preliminary study on the
perceived advantages and barriers, in: 2018 IEEE International Conference on Software Maintenance
and Evolution (ICSME), 2018, pp. 564–568. doi:10.1109/ICSME.2018.00068.
[24] M. Wyrich, J. Bogner, Towards an autonomous bot for automatic source code refactoring, in: 2019
IEEE/ACM 1st International Workshop on Bots in Software Engineering (BotSE), 2019, pp. 24–28.
doi:10.1109/BotSE.2019.00015.</p>
    </sec>
  </body>
  <back>
    <ref-list>
      <ref id="ref1">
        <mixed-citation>
          [1]
          <string-name>
            <given-names>A.</given-names>
            <surname>Révész</surname>
          </string-name>
          ,
          <string-name>
            <given-names>N.</given-names>
            <surname>Pataki</surname>
          </string-name>
          ,
          <article-title>Integration heaven of nanoservices</article-title>
          ,
          <source>in: Proceedings of the 21st International Multi-Conference INFORMATION SOCIETY</source>
          , IS'
          <year>2018</year>
          , volume Volume G: Collaboration,
          <source>Software and Services in Information Society</source>
          ,
          <year>2018</year>
          , pp.
          <fpage>43</fpage>
          -
          <lpage>46</lpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref2">
        <mixed-citation>
          [2]
          <string-name>
            <given-names>Á.</given-names>
            <surname>Révész</surname>
          </string-name>
          ,
          <string-name>
            <given-names>N.</given-names>
            <surname>Pataki</surname>
          </string-name>
          , Visualisation of Jenkins pipelines,
          <source>Acta Cybernetica</source>
          <volume>25</volume>
          (
          <year>2021</year>
          )
          <fpage>877</fpage>
          -
          <lpage>895</lpage>
          . URL: https://cyber.bibl.u-szeged.hu/index.php/actcybern/article/view/4119. doi:
          <volume>10</volume>
          .14232/actacyb. 284211.
        </mixed-citation>
      </ref>
      <ref id="ref3">
        <mixed-citation>
          [3]
          <string-name>
            <given-names>B.</given-names>
            <surname>Stroustrup</surname>
          </string-name>
          ,
          <article-title>Thriving in a crowded and</article-title>
          changing world: C+
          <article-title>+ 2006</article-title>
          <volume>-2020 4</volume>
          (
          <year>2020</year>
          ). URL: https: //doi.org/10.1145/3386320.
        </mixed-citation>
      </ref>
      <ref id="ref4">
        <mixed-citation>
          [4]
          <string-name>
            <given-names>P.</given-names>
            <surname>Pirkelbauer</surname>
          </string-name>
          ,
          <string-name>
            <given-names>D.</given-names>
            <surname>Dechev</surname>
          </string-name>
          ,
          <string-name>
            <given-names>B.</given-names>
            <surname>Stroustrup</surname>
          </string-name>
          ,
          <article-title>Source code rejuvenation is not refactoring</article-title>
          , in: J. van Leeuwen,
          <string-name>
            <given-names>A.</given-names>
            <surname>Muscholl</surname>
          </string-name>
          ,
          <string-name>
            <given-names>D.</given-names>
            <surname>Peleg</surname>
          </string-name>
          ,
          <string-name>
            <given-names>J.</given-names>
            <surname>Pokorný</surname>
          </string-name>
          ,
          <string-name>
            <surname>B.</surname>
          </string-name>
          Rumpe (Eds.),
          <source>SOFSEM 2010: Theory and Practice of Computer Science</source>
          , Springer Berlin Heidelberg, Berlin, Heidelberg,
          <year>2010</year>
          , pp.
          <fpage>639</fpage>
          -
          <lpage>650</lpage>
          . doi:
          <volume>10</volume>
          . 1007/978-3-
          <fpage>642</fpage>
          -11266-9_
          <fpage>53</fpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref5">
        <mixed-citation>
          [5]
          <string-name>
            <given-names>T.</given-names>
            <surname>Brunner</surname>
          </string-name>
          ,
          <string-name>
            <given-names>N.</given-names>
            <surname>Pataki</surname>
          </string-name>
          ,
          <string-name>
            <given-names>Z.</given-names>
            <surname>Porkoláb</surname>
          </string-name>
          ,
          <article-title>Backward compatibility violations and their detection in C++ legacy code using static analysis</article-title>
          ,
          <source>Acta Electrotechnica et Informatica</source>
          <volume>16</volume>
          (
          <year>2016</year>
          )
          <fpage>12</fpage>
          -
          <lpage>19</lpage>
          . URL: http://aei.tuke.sk/papers/2016/2/03_Bruner.pdf.
        </mixed-citation>
      </ref>
      <ref id="ref6">
        <mixed-citation>
          [6]
          <string-name>
            <given-names>W.</given-names>
            <surname>Lucas</surname>
          </string-name>
          ,
          <string-name>
            <given-names>F.</given-names>
            <surname>Carvalho</surname>
          </string-name>
          ,
          <string-name>
            <given-names>R. C.</given-names>
            <surname>Nunes</surname>
          </string-name>
          ,
          <string-name>
            <given-names>R.</given-names>
            <surname>Bonifácio</surname>
          </string-name>
          ,
          <string-name>
            <given-names>J.</given-names>
            <surname>Saraiva</surname>
          </string-name>
          ,
          <string-name>
            <given-names>P.</given-names>
            <surname>Accioly</surname>
          </string-name>
          , Embracing modern C+
          <article-title>+ features: An empirical assessment on the KDE community</article-title>
          ,
          <source>Journal of Software: Evolution and Process</source>
          <volume>36</volume>
          (????) e2605. URL: https://onlinelibrary.wiley.com/doi/abs/10.1002/smr.2605. doi:https: //doi.org/10.1002/smr.2605.
        </mixed-citation>
      </ref>
      <ref id="ref7">
        <mixed-citation>
          [7]
          <string-name>
            <given-names>E.</given-names>
            <surname>Fülöp</surname>
          </string-name>
          ,
          <string-name>
            <given-names>A.</given-names>
            <surname>Gyén</surname>
          </string-name>
          ,
          <string-name>
            <given-names>N.</given-names>
            <surname>Pataki</surname>
          </string-name>
          , C++
          <article-title>source code rejuvenation for an improved exception specification</article-title>
          ,
          <source>in: 2022 IEEE 16th International Scientific Conference on Informatics (Informatics)</source>
          ,
          <year>2022</year>
          , pp.
          <fpage>94</fpage>
          -
          <lpage>99</lpage>
          . doi:
          <volume>10</volume>
          .1109/Informatics57926.
          <year>2022</year>
          .
          <volume>10083493</volume>
          .
        </mixed-citation>
      </ref>
      <ref id="ref8">
        <mixed-citation>
          [8]
          <string-name>
            <given-names>D.</given-names>
            <surname>Kolozsvári</surname>
          </string-name>
          ,
          <string-name>
            <given-names>N.</given-names>
            <surname>Pataki</surname>
          </string-name>
          ,
          <article-title>A static analysis approach for modern iterator development</article-title>
          ,
          <source>Annales Mathematicae et Informaticae</source>
          <volume>59</volume>
          (
          <year>2023</year>
          )
          <fpage>37</fpage>
          -
          <lpage>53</lpage>
          . doi:
          <volume>10</volume>
          .33039/ami.
          <year>2023</year>
          .
          <volume>08</volume>
          .006.
        </mixed-citation>
      </ref>
      <ref id="ref9">
        <mixed-citation>
          [9]
          <string-name>
            <given-names>T.</given-names>
            <surname>Brunner</surname>
          </string-name>
          ,
          <string-name>
            <given-names>Z.</given-names>
            <surname>Porkoláb</surname>
          </string-name>
          ,
          <article-title>Programming language history: Experiences based on the evolution of C++</article-title>
          ,
          <source>in: Proceedings of the 10th International Conference on Applied Informatics</source>
          ,
          <year>2017</year>
          , pp.
          <fpage>63</fpage>
          -
          <lpage>71</lpage>
          . doi:
          <volume>10</volume>
          .14794/ICAI.10.
          <year>2017</year>
          .
          <volume>63</volume>
          .
        </mixed-citation>
      </ref>
    </ref-list>
  </back>
</article>