[Tex/LaTex] Wrong figure references using subfig

cross-referencingsubfloats

I'm using the subfig package to handle subfigures and I'm getting a really puzzling error, where referencing with \ref{} to a subfigure assigns it the wrong figure number, even though the reference to the global figure does work:

A MWE example is the following:

\documentclass{report}

\usepackage{subfig}
\usepackage{caption}
\usepackage{lmodern} 
\usepackage{bm}

\begin{document}

\chapter{Title}

\captionsetup[figure]{position=top}
\begin{figure}[!htbp]
  \centering
  \begin{tabular}{cc}
  \subfloat{
    \label{fig1a}
    \rule{3cm}{2cm}
  }
  &
  \subfloat{
    \label{fig1b}
    \rule{3cm}{2cm}
  }
  \end{tabular}
  \caption{Sample caption.}
  \label{fig1}
\end{figure}


\begin{figure}[hbt]
  \centering
  \subfloat{
    \rule{3cm}{2cm}
    \label{fig2a}
  }
  \hspace{5mm}
  \subfloat{
    \rule{3cm}{2cm}
    \label{fig2b}
  }
  \caption{
  Referencing inside the caption.
  \texttt{\textbackslash subref\{fig2a\}}: \protect\subref{fig2a}, 
  \texttt{\textbackslash subref\{fig2b\}}: \protect\subref{fig2b}, 
  \texttt{\textbackslash subref*\{fig2a\}}: \protect\subref*{fig2a}, 
  \texttt{\textbackslash subref*\{fig2b\}}: \protect\subref*{fig2b},
  \texttt{\textbackslash ref\{fig2a\}}: \protect\ref{fig2a},
  \texttt{\textbackslash ref\{fig2b\}}: \protect\ref{fig2b},
  \texttt{\textbackslash ref\{fig2\}}: \protect\ref{fig2}.
  }
  \label{fig2}
\end{figure}

Subref works correctly: 
  \texttt{\textbackslash subref\{fig2a\}}:~\protect\subref{fig2a}, 
  \texttt{\textbackslash subref\{fig2b\}}:~\protect\subref{fig2b}, 
  \texttt{\textbackslash subref*\{fig2a\}}:~\protect\subref*{fig2a}, 
  \texttt{\textbackslash subref*\{fig2b\}}:~\protect\subref*{fig2b}.

$\quad$

Figure ref works correctly:
  \texttt{\textbackslash ref\{fig2\}}:~\protect\ref{fig2}.

$\quad$

Direct ref to subfigures doesn't:
  \texttt{\textbackslash ref\{fig2a\}}: \protect\ref{fig2a},
  \texttt{\textbackslash ref\{fig2b\}}: \protect\ref{fig2b},

\end{document}

What causes this, and how can I fix it?

Best Answer

This turns out to be a very subtle error in terms of how the \captionsetups are handled. This behaviour goes away when the initial \captionsetup is removed, or when

\captionsetup[figure]{position=auto}

is placed between the two:

I hesitate to call this a bug because this is possibly not quite how subfig is meant to be used (though let's face it, when was the last time that a LaTeX package cared about how its users would respond to it and try to use it?), but it looks pretty buggy to me.

(And, if this looks obvious to anyone, consider that the two figures can be on different subfiles of a very long document (so good luck debugging that), that the second figure doesn't really need to invoke any \captionsetup because it doesn't need it, and that if the first figure tries to clean up after itself by setting position=auto, and the second file is not included when the top figure is first introduced (fairly reasonable), then subfig is prone to raise a warning that there are unused \captionsetups, actively fighting this fix.)