If b contains the literal string printf "%s\n" "$a", i.e. you didn't expand $a into it before hand, then yes, eval "$b" should be fine. Not sure why you'd need eval there, though, since you just have a static command. Just run printf "%s\n" "$a" directly.
You said in comments you want to store some commands for future use. That's the job of functions. E.g. that printf command could be made into a function like this:
println() {
printf "%s\n" "$1"
}
which you run as println "hello there", println "$a" or whatever. "$1" is the first argument to the function, but of course you could read stdin instead, or use multiple arguments ("$2", "$3", ...; or all of them as a list "$@" (alike "${array[@]}")).
Similarly for the longer set of operations:
#!/bin/bash
say_hi() {
echo "hello, $1"
}
louder() {
echo "$1!"
}
funcs=(say_hi louder)
names=(Huey Dewey Louie)
for name in "${names[@]}"; do
tmp=$name
for func in "${funcs[@]}"; do
tmp=$($func "$tmp")
done
echo "result: $tmp"
done
evaled is fixed (as it is here), but in that case why bother witheval? On the other hand, if the string is constructed dynamically, you need to take care to constrain how it's constructed to make sure it's safe.a='"; echo "hi'is a negative example.eval "$b"just prints"; echo "hi. I can see howeval "$a"is dangerous though.