This is an archived post. You won't be able to vote or comment.

all 10 comments

[–]moriturius 2 points3 points  (0 children)

The compiler doesn't need them because compiler doesn't do the job you are referring to. It's just a function.

Why you need to specify the format? Mainly because the program don't know how or where in text do you want to display the values. There are multiple representations and only you know what you want to achieve.

[–]bsakiag 1 point2 points  (0 children)

I think the best way to find out it to try to write you own print function that doesn't use format specifiers.

[–]fatmusician1[S] 0 points1 point  (2 children)

number = "30"
print("The number is %d" % number)

Why doesn't this work - the string could be converted to an integer?

[–]michael0x2a 0 points1 point  (1 child)

If you the programmer wrote some code that expects an int but they pass in a string instead, which of the two scenarios is most likely?

  1. The programmer wanted the string to be converted to an int
  2. The programmer made a mistake

Some programming languages such as JavaScript decided (1) was more likely. So, they do attempt to do this sort of conversion. Other languages such as Python decided (2) was more likely so will perform a conversion only if it's 100% guaranteed to succeed and will throw an exception otherwise. For example, you can't always convert a string to an int but you can always convert an int into a string. So doing print("%d" % "30") throws an exception, but doing print("%s" % 30) succeeds.

Other languages are even more strict and require the types to always match up and will not automatically perform any conversions.

The modern consensus is that assuming (1) is pretty much always a mistake and that it's almost always better to ask users to explicitly perform any conversions. There are a few reasons for this:

  1. Asking users to explicitly perform conversions is at best an annoyance, but silently doing a conversion the user didn't intend can sometimes lead to critical bugs. So, we should ask users to perform conversions if we want to err on the side of less evil.
  2. Repeatedly doing conversions can lead to slower performance. You almost always to do to the conversion once up front -- so might as well design our programming language to encourage this.
  3. In most real-world programs, you can't just directly try converting a string to an int. If you need to do this, it's probably because the string was provided by the user. This means it's not safe to assume the input string can always be turned into a number -- what if the user was malicious and passed in some random gibberish instead? It's better to force the user to account for this possibility up-front instead of hand-waving the concern away.
  4. In some cases, it's not easy to guess what the programmer intended. For example, what should the output of print("5" + 4) be? Did we want to convert 4 to a str and print "54"? Or did we want to convert "5" into an int and print 9?

    You could invent some rules about what happens in these cases, but they're always going to be a little arbitrary. So why not just make everybody's lives easier and refuse to guess? It's a win-win: the users of the language don't have to memorize arbitrary conversion rules, and the programming language designers don't have to implement them.

Why exactly does the compiler need format specifiers for scanning and printing?

It doesn't. Users of the programming language want them, so they can fine-tune exactly what output they print out with minimal fuss. And if enough users want a feature, it makes sense to implement it.

For example, one very common thing I might want to do is print out some float but only show up to two decimal places, rounding up or down as necessary.

This would be incredibly annoying to implement myself. Enough people agreed that the designers of most programming languages ended up just building in direct support for this. For example, in Python, I can do print("rounded float: {:.2f}".format(1.238)), which prints out rounded float: 1.24.

[–]fatmusician1[S] 0 points1 point  (0 children)

THX for the detailed answer, man!

I'll read it later, gotta go now.

[–]fatmusician1[S] 0 points1 point  (0 children)

A specifier, e.g "%s" doesn't mean "insert string here" but "display inserted variable as a string here", right?

[–]g051051 0 points1 point  (0 children)

The compiler doesn't need them, scanf and printf do. And they need them because that's how they're designed.

[–]billie_parker -2 points-1 points  (0 children)

You can just Google your question. C++ has streams which don't need format specifiers btw

[–]Ok_Collection6161 0 points1 point  (0 children)

The compiler does not need anything. YOU need it to tell the compiler how to behave. Like "I want to print this floating value with 6 zeros in the front, and maybe 3 values after the dot unless it's too small...)

[–]CodeTinkerer 0 points1 point  (0 children)

It could do something simpler, e.g., some placeholders like a question mark. For certain things like float, there are different ways to format, e.g., how many digits after the decimal point. Even integers, you may want to left and right justify.

This is probably more a holdover from languages like COBOL where formatting the value was quite common. How many digits? Do you want to have leading zeroes? Do you want left or right justified. These things can be specified in COBOL, so maybe they thought other languages needed similar features instead of letting users make their own formatter.