Unformatted vs. formatted input.

Pages: 12
@Cubbi
I'll dumb it down for you:

cin is part of the istream library, and it requires input (istream input). Because it only takes 1 piece of data at a time, if more than 1 piece of data is fed to it (like "i play in a sand box", cin>> string will only get "i" from that), then it gets the first piece of data, and stores the rest in a buffer. What sync does is sync that buffer. So, when you enter more than 1 piece of data, the buffer is synced, and when cin is used again, there is no data to get from the buffer, so it prompts for input.

Basically it "syncs the istream input buffer". SIMPLE.
Define sync. Why is it non-portable? These are my inquires.
I'm not going to start defineing to you what can be easily be looked up in a dictionary.

As for why it isnt portable: Portable between what? OS'? any computer?
Last edited on
IWishIKnew wrote:
As for why it isnt portable: Portable between what? OS'? any computer?

As I said, on the majority of implementations (compilers + iostream libraries), this function does exactly nothing for std::cin.
sync is very portable. But your results with sync can vary depending on the way it's used. A very good example of this was in an example I was reading about multithreading. You "sync" the output stream so the streams don't add into each other's buffers. Each system (unsure about what is actually implemented specifically between systems (OS, Compiler, etc.)) handles the "buffer" differently.

sync does exactly that, it syncs the stream within that stream class (cin in this example). It doesn't "discard" the buffer, just handles it differently, forcing the stream to handle it's "buffer" before moving onto the next instance of the stream. Again, this doesn't mean the stuff is discarding and you shouldn't use sync to do so.

This explanation isn't very technical, but Cubbi is right. You should really consider using the ignore function as it was designed specifically to clear the buffer.
sync is very portable. But your results with sync can vary


Make up your mind =P

Portable = behaves the same way consistently on other platforms.

If your results can vary, then it is not portable.
If you asked me to synchronize with something I wouldn't also remove it. My confusion stems from the reference here actually:
Synchronizes the buffer associated with the stream to its controlled input sequence. This effectively means that the unread characters in the buffer are discarded.


What I'm starting to think is that sync is designed for std::ios/std::streambuf, but not particularity std::cin. Way off?
@Disch
sync is portable, from what I understand about it. But it doesn't mean that other compilers/OS's/whatever can't add in some different definition to it. It was designed to sync the streams, period. Some compilers might have implemented it to clear the buffer as well, but that wasn't standard. What I believe I mean is that the function is included in the standard library (which means portable to me) but it could be handled differently by a different compiler. I've been trying to think of an example of another standard feature that's handled differently, but I can't think of any off the top of my head (but I assume that Microsoft is to blame for the non standard way of implementing it).

@LowestOne
Technically, I don't believe it's wrong. I just don't think it should have included that the characters in the buffer are discarded in there because some readers might think that using sync was designed to clear the buffer, which it isn't (atleast that isn't it's intent), or that it was designed to ignore the buffer, which it isn't (atleast that isn't it's intent either).

Maybe that clears it up more?
Last edited on
Many implementations of basic_filebuf do in fact"roll back" the unread buffer for the files open for reading: the input buffer becomes empty and the file position is moved back. The next input operation will then cause the input buffer to get re-filled. This has the effect of re-reading any changes just made to the file, that is, synchronizing.

In fact, in GCC, if you attempt to cin.sync() and trace the program, you will see it attempt calling lseek() on stdin and failing since stdin does not support this operation. Clang++ is smart enough to attempt nothing. Sun and IBM also do nothing (although I didn't trace to see why).
Another example of something being portable but being implemented different is C style arrays. The standard says an array must accept a constant number greater than zero. However, when using the g++ compiler, this code compiles:
1
2
int a =4;
char myCharArray[4];


There are compiler flags that can be set to prevent something like this from being allowed. My book actually just covered it an called it an "extra" feature of the compiler implementation of the standard. The standard allows a variable to be used but specifies that it must be a constant expression. In this instance, instead of the compiler doing an extra feature than what the standard is (when compared to the sync standard) it reduces the requirements to using the standard.

That was a slightly different scenario, but what should be taken from it is that even though you're using some standard feature, if it's doing something other than what was part of the standard, it doesn't mean it is standard (meaning that it doesn't do the same on every system).

Putting this into perspective, sync() syncs the buffer. If an implementation of the standard library changes how sync works, it doesn't mean you should use that function because of the implementation, but because of what the standard says sync() does. If you want to clear the buffer, use clear(), if you want to ignore stuff in the buffer, use ignore(), but don't use sync just because your implementation combines it essentially all into one. This is a basic form of bad programming due to not understanding what the functions actually do.
sync is portable, from what I understand about it. But it doesn't mean that other compilers/OS's/whatever can't add in some different definition to it.


Using sync for what it's designed to do is portable.

Using sync for an additional feature that XX compiler adds to it is not portable.

Another example of something being portable but being implemented different is C style arrays. The standard says an array must accept a constant number greater than zero. However, when using the g++ compiler, this code compiles:


Nonstandard compiler extensions are not portable.... they're compiler dependent. Something that is compiler dependent cannot possibly be portable -- it directly contradicts the meaning of the word "portable".

"<xxxx> dependent" and "portable" are exact opposites.


"Yes, this code is portable, but only if you compile it with GCC ver 5.2 for Windows" <-- that is nonsense.


Putting this into perspective, sync() syncs the buffer. If an implementation of the standard library changes how sync works, it doesn't mean you should use that function because of the implementation, but because of what the standard says sync() does. If you want to clear the buffer, use clear(), if you want to ignore stuff in the buffer, use ignore(), but don't use sync just because your implementation combines it essentially all into one. This is a basic form of bad programming due to not understanding what the functions actually do.


I agree 100%
Disch wrote:
Nonstandard compiler extensions are not portable.... they're compiler dependent. Something that is compiler dependent cannot possibly be portable -- it directly contradicts the meaning of the word "portable".

"<xxxx> dependent" and "portable" are exact opposites.


"Yes, this code is portable, but only if you compile it with GCC ver 5.2 for Windows" <-- that is nonsense.


When I meant the code is portable, declaring a C-Style array is portable. Declaring it using a non constant value isn't. My example covered how declaring the array would be the same on all systems, but instead how the g++ compiler implemented accepting a non constant value was not portable.
Topic archived. No new replies allowed.
Pages: 12