I think there are a handful of problems unique to the software industry that make accurate estimation practically impossible. Mostly they're a sign of an immature industry. So, as a lot of comments here suggest, most people just give it their best guess, and then inflate the number a lot, and negotiate some kind of deal, and then work like hell to actually pull it off.

1. It's never repeatable. Nearly every single thing built in software is being built for the first time. Even if it's some government CRUD application, and even if you're leveraging sixteen popular software frameworks to build it, that application will still be in some way different from other applications in the same niche. There's no blueprint for building software; mechanics have a gigantic (sometimes accurate) database of the time required to do a variety of jobs, tract home builders are all building the same thing over and over ... the closest that software ever gets to that is themes or skins for frontend UI, and even those inevitably end up getting customized in some way.

2. Nobody wants to pay to build a blueprint. The only way in the software industry to figure out how complex a particular application is going to be is to build it. Developing an accurate spec is exactly as expensive as building the actual application. This is because the "engineering" part of software engineering is still practically nonexistent.

3. And while we're on the topic of engineering: there are no standards. Or, there are thousands of different standards, depending on how you look at it. That CRUD application could be built with one of many different interfaces -- should it emulate data entry terminals, with simple tab-navigable text fields? Should it use Google's "Material" UI? Bootstrap? There's no comprehensive study which has compared the amount of end user effort required to use each interface, and therefore there's no industry standard which says, "this is always the right way to build this thing given these constraints". Compare to something like a low voltage contractor's license, which expects you to be familiar with the different types of cable to use in different building environments.

4. It's buggy as hell. Ok, so you're experienced enough to navigate your way through everything else up above and not get burned too badly. You have a preferred toolkit, you specialize in a particular niche, cool. Well, today, Chrome just released an update that broke the way your application handles cached content. (Happened to me.) The vendor for one of your frameworks released an urgent security update that completely broke critical functionality in an unrelated part of the application. (Happened to me.) The two libraries you're using together, which don't use any of the same globals and should be entirely isolated from eachother, are still somehow interfering in a way that's not covered by the sparse documentation. (Happened to me.) There are millions upon millions of lines of code involved in every single interaction with a computer now, and they are imperfect. Many of them are written by amateurs, people who -- even though they're getting paid to write code -- have only been in the industry for a couple of years and they're still re-learning all of the same lessons that everyone else before them had to learn through trial and error.

5. Too many programmers like shiny new things. We could fix a lot of the above if we slowed down and "refactored" our industry -- started doing real usability studies, establishing standards for storing sensitive information, more rigorously separating security and feature updates. But, nobody really wants to do that. They want the new thing: the new programming language, the new framework, the new browser feature, the new toolchain. I think this is largely because while programmers spend a lot of their time talking to machines, they aren't machines themselves. They need a steady stream of new stuff to stave off the boredom. It's also a good way to improve your resume or income. If a new Widget comes out, and you immediately learn Widget, you're now one of very few people in the world that knows Widget. Now, if you convince your bosses or customers to use Widget, you're the only person that they can go to for help with Widget.

So there's a lot of immaturity, and it's kind of a mess, but it's also a pace of technological development that's unprecedented in the history of humankind.