Whether software engineering is "real" engineering is a perennial question among programmers with status anxiety.They shouldn't worry, as a surgeon friend told me there are only 5 acceptable careers for his children: doctor (surgeon or specialist only), lawyer (maybe), consultant (at a good firm), finance (at a good firm), and successful entrepreneur. Programmer/engineer is not on the list. My own views on this have shifted over the years but go back to when I was in college. At the time it was obvious to me that programming was not engineering because programming involved so much revising, debugging, and head-scratching before things would finally work properly, and even then there were usually underlying problems that wouldn't come to light until later.
At dinner with a family friend one night I was explaining the state of things. This friend has had a long, successful career as a civil engineer, and was now mostly retired but still did some expert witness consulting for when things went wrong in the real world. I expected him to agree with me that software engineering obviously wasn't, so I was surprised when he laughed and said nothing ever goes as planned in civil engineering either. Things don't fit together the way you expect, you don't get materials on time or as specified, etc. This made me question whether I was wrong about software engineering.
One interesting difference between "real" engineering and software engineering is that in real engineering the production is often done by technicians, rather than engineers. I think this gives a clue to what makes something real engineering. In real engineering it is theoretically possible to design a working artifact without ever making it in reality.I realize that in practice this often doesn't work, and engineers who do not have experience with the physical side of product development are often poor engineers who do not adequately plan for things like stress raisers, fatigue life, etc. This is possible because the engineer can model the system in such a way that he can predict how it will perform in practice.If you read any engineering textbooks this modeling quickly gets very complicated and mathematical, but in practice most engineers are much more intuitive/heuristic in their actual design process and use these more complicated techniques to verify that everything works appropriately (if they use them at all).
With this in mind, I think much programming is engineering, but some isn't. And it isn't just about complexity or difficulty. An injection mold for a toy solider is just as much an engineered product as a rocket motor, even if the rocket motor is far harder to design. Instead, the dividing line is something like: did you have specific requirements with regards to performance, cost, reliability, and functionality that the software had to meet (even if these were just in your head and not written down anywhere), and did you design the software to meet these requirements? If you can answer yes to these questions it is engineered. If you can't then it's not. Simple.