Calling a function using the B::foo syntax is perfectly legal in general.
The exception detailed in the C++ standard is that when you have a pure virtual function that you do not call via B::foo, you do not have to define it. 10.4/2: (via @jrok)
[...] A pure virtual function need be defined only if called with, or as with (12.4), the qualified-id syntax (5.1). [...]
The B::foo() syntax is an example of calling foo with the qualified-id syntax. Note that this is distinct from the (this->*&B::foo)() syntax, which does a virtual table lookup.
A pure virtual function is not "setting the function to a null pointer" despite the =0 syntax. Rather, it is marking it as "in order to instantiate this class, I require that a descendent override this method". As it happens, compilers tend to set the virtual function table of a pure virtual function to point to an error handler that sets up an error (at least in debugging) that you made a pure virtual function call, because that is pretty cheap to set up, and it diagnoses calls to said method during construction/destruction before or after the descendent class instance lifetimes.
You can mark a method as pure virtual even if your parent defined it. This just indicates that your child implementations have to override it again. You can mark a method as pure virtual even if you define it. Again, this just tells your child implementations that they have to override it.
As a bonus answer, why would we do this? Sometimes you want to implement a partial implementation in a base class, to be invoked before or after the child implementation. Other times you want a default implementation. In each case, you want some code to be coupled to this method, and you want to force children to override it.
You could implement the before/after/default in a distinct non-virtual method called before_foo or default_foo, or you could just do this.
At other times, in a deep hierarchy the implementation of some method inherited from above may no longer be valid. So you'll =0 it to indicate that children have to override it again.
Both cases are extreme corner cases.
The final spot I've used this technique is when I wanted to do away with the (bar->*&Bar::foo)() annoyance. I override Bar::foo to do (this->*&Bar::foo)(), allowing bar->Bar::foo() to do the right thing "magically".