-5

How can I translate a loop like the below one to C style?

for (auto element : vector) {
   Do_Somethin();
}
Hazem Abaza
  • 331
  • 4
  • 21
  • 1
    @JohnnyMopp It doesn't matter. – Asteroids With Wings Aug 05 '20 at 14:43
  • 2
    `Is there a tool`... – kesarling He-Him Aug 05 '20 at 14:43
  • there is no `C` style for loop!!!! –  Aug 05 '20 at 14:53
  • 4
    Recommendation: Don't translate code from one language to another. Even when the code does have a more-or-less literal translation, it might not make sense overall in the context of the new program. Understand the observable behaviour of the original program and implement identical behaviour in the new language using the new language's idioms and following its best practices. Then exhaustively test both programs to ensure the observable behaviour is identical. To do this you need to understand both languages fairly well. – user4581301 Aug 05 '20 at 14:55
  • I have a tool which detect loop bounds only in C but the code is written in C++ – Hazem Abaza Aug 05 '20 at 14:57
  • You translate the loop by knowing what that loop means, and then implementing the same loop in the language you're translating to. Look at it in the long run -- today it's the loop, tomorrow it will be something else that exists in C++ that doesn't exist in C. – PaulMcKenzie Aug 05 '20 at 14:57
  • 1
    "_I have a tool which detect loop bounds only in C but the code is written in C++_" - Is this limitation of the tool the reason you are translating the code? If so - don't! Drop that tool and get a tool suitable for analyzing C++ code. – Ted Lyngmo Aug 05 '20 at 14:59
  • 1
    Yes, do not write code so that it fits a third-party tool. That tool you're using now, whatever it is, will probably not be able to detect lambda syntax, move assignment and move copy operations, etc. – PaulMcKenzie Aug 05 '20 at 15:01
  • `for (size_t index = 0; index < sizeof vector/sizeof *vector; index++) { do_somethin(vector[index]); }` – pmg Aug 05 '20 at 15:01
  • The tool analyze normal applications in C , my application is in C++ and here is the point – Hazem Abaza Aug 05 '20 at 15:01
  • @HazemAbaza Then, drop that tool. It's not the correct tool. – Ted Lyngmo Aug 05 '20 at 15:02
  • 5
    @HazemAbaza -- C and C++ are two different languages. – PaulMcKenzie Aug 05 '20 at 15:02
  • 2
    @HazemAbaza -- But why do you need bounds analysis for a range-based `for`? It already has built-in bounds analysis. – PaulMcKenzie Aug 05 '20 at 15:04
  • @HazemAbaza If you don't drop that tool, you'll be transforming the C++ program into C-ish looking code bit by bit. It'll be a horrible mess and noone will understand why you did what you did. – Ted Lyngmo Aug 05 '20 at 15:11
  • 1
    @HazemAbaza -- A lot of errors that would usually come with a C program, such as loop boundary errors, are easily alleviated in C++ by using range-base `for` loops, using algorithm functions instead of writing `for` loops, etc. Thus you using such a tool for `C` programs makes very little, if any sense. – PaulMcKenzie Aug 05 '20 at 15:15
  • 3
    _Is there a way to use it for C++ code?_ **No.** Ask the vendor of the tool if they have a similar tool but for C++. – Eljay Aug 05 '20 at 15:16
  • but this is the only available tool. Re-implementing it would consume a lot of time – Hazem Abaza Aug 06 '20 at 10:04
  • *but this is the only available tool* -- So I guess you will translate your C++ to C so that you can make use of this tool. Otherwise what is there to discuss further? – PaulMcKenzie Aug 06 '20 at 20:24

2 Answers2

5

You'd start with converting it to a non-ranged-based for loop.

{
  auto&& range = Chains;
  using std::begin; using std::end; // possibly cbegin/cend
  auto it = begin(range); // possibly cbegin
  auto end = end(range); // possibly cend
  for(; it!=end; ++it) {
    auto block = *it;
    // body of loop
  }
}

then you tease apart each piece.

Start by deducing what the auto variables are. Guess if you have to, then do a static_assert( std::is_same_v< decltype(begin), your_guess > ); to confirm. Once you have confirmed, replace. DO NOT guess and swap in the type and assume "it compiles, I got it right"; that can lead to subtle bugs.

Then replace begin and end with an equivalent expression. You'll have to do some research (it could be raw pointers into arrays, or it could be .begin methods, or it could be a free begin function in the namespace of the range expression).

What happens next depends on what your iterators are here. Are they plain pointers? If so, the problem is probably pretty easy. If not, you have more work to do.

Finally, remove all references, and then tidy up.

Ideally you'd want to do each of these steps as a git commit with unit tests confirming no change of behavior. You appear not to be qualified to make these changes without such testing. That is ok, and the unit testing will have value.


Going the other way, there are C++ to C translators. They will generate unreadable and unmaintainable code in practice.

But the output can be compiled by a C compiler.

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
2

Yes, you can always exchange ranged-for for a classic for loop.

For ranged-for to work, Chains must be of a type that implements an iterator interface, or must be an array.

If it's an array, you know what to do.

Otherwise, you can write the loop as:

for (auto it = Chains.begin(), end = Chains.end(); it != end; ++it)
{
   auto block = *it;
   Do_Somethin();
}

(Though, possibly, you may need cbegin() if only a const interface is available and begin() has no const overload for some reason.)

If the type of Chains supports random access with operator[], you could also try something like this:

for (std::size_t i = 0; i < Chains.size(); ++it)
{
   auto block = Chains[i];
   Do_Somethin();
}

… though you'll need to look at the documentation to find out what .size() should actually be.

Now of course C doesn't have iterators, or auto, but then it doesn't have classes either. You can choose to substitute replacements for those features as well if you like.

Asteroids With Wings
  • 17,071
  • 2
  • 21
  • 35