ds: was added by IDA, not by the compiler. If you look at the raw opcode bytes, you will see that there is no DS override prefix in the instruction. It's silly that it does this.
IDA adds that
ds: prefix because otherwise you wouldn't know that this is an indirect call--that is, that it's reading a 32-bit variable at an address named
__imp__printf then calling the address stored in that variable. Without the
ds:, it would be just be calling
If IDA used a better assembly language syntax--namely, the nasm syntax--that instruction would look like simply this, using brackets to show that it is a memory read (and
dword to distinguish from a few other weird types of
.text:00411279 call dword [__imp__printf]
Windows, like pretty much every other 32-bit OS, has a flat address space. CS, DS, ES and SS all have the same base address, 0, so it doesn't matter which segment you use as your base. (Except that you can't do a memory write if CS is your segment.) FS and GS have different bases, since the major OS's all use them for thread-local storage, but those will always have explicit prefix bytes in the instruction.