MATLAB: Logical converting to double for no reason – bug

data type conversionlogical?MATLAB

I have a function that reads data from a text file and returns a structure with the data. One field of the data should be logical and one field should be double. When I run this function one time, the field that should be logical is logical. Great. But when I run the function again, the data type of the field that should be logical is double. Is there any explanation for this?
The first thing I did was try to debug it by putting a breakpoint at the line that assigns the logical data to output. To my surprise, simply the act of placing a breakpoint here fixes the problem. This is true even if I make the breakpoint conditional and the condition always evaluates to false.
I've also discovered that the problem goes away when I clear the function using the "clear" command.
Here is my function:
function Data = readData2(DataFile)
fp = fopen(DataFile,'r');
Data.boolVar = getVariable(fp);
Data.scalarVar = getVariable(fp);
fclose(fp);
end
function val = getVariable(fp_in)
keep_going = true;
while keep_going
txt = fgetl(fp_in);
if strcmp(txt(1),'>')
val = parseData(txt);
keep_going = false;
end
end
end
function val = parseData(str)
if isempty(strfind(str,'<'))
str = [str ' <'];
end
toks = regexp(regexp(str,'(?<=> ).*(?= <)','match'),'\S+','match');
toks = toks{1};
for i = 1:length(toks)
valstr = toks{i};
if strcmp(valstr,'T')
val(1,i) = true;
elseif strcmp(valstr,'F')
val(1,i) = false;
else
val(1,i) = str2double(valstr);
end
end
end
And the text file it is reading:
* data_file.txt
*--------------------------------------------
* Comment Comment Comment
*------------------------------------------------
* Comment Blah Blah
*------------------------------------------------
* boolean variable 1
> T T T T
*
*
* Comments
*
*
* 3 more variables
> 0.4 -0.3 -0.3 0.6
> 0.4 0.9 -0.4 -0.8
> 0.7 0.1 0.2 0.3
*
* another variable
> 3
*
* More comments
Here is a tester script that demonstrates my problem:
clear all
clc
islogicaldisp = @(x) disp([' isa(Data.boolVar,''logical'') = ' num2str(isa(x,'logical'))]);
isdoubledisp = @(x) disp([' isa(Data.boolVar,''double'') = ' num2str(isa(x,'double'))]);
Data = readData2('data_file.txt');
disp('First pass:');
islogicaldisp(Data.boolVar)
isdoubledisp(Data.boolVar)
Data = readData2('data_file.txt');
disp('Second pass - converted to double!?!?:');
islogicaldisp(Data.boolVar)
isdoubledisp(Data.boolVar)
Data = readData2('data_file.txt');
disp('Third pass - just to make sure...:');
islogicaldisp(Data.boolVar)
isdoubledisp(Data.boolVar)
dbstop in readData2 at 34 if false
disp('Fourth pass - this time add an inactive breakpoint:');
Data = readData2('data_file.txt');
islogicaldisp(Data.boolVar)
isdoubledisp(Data.boolVar)
disp(' What?? ^^^^^^^^^');
dbclear in readData2
disp('Fifth pass - deactivate breakpoint and try again:');
Data = readData2('data_file.txt');
islogicaldisp(Data.boolVar)
isdoubledisp(Data.boolVar)
Data = readData2('data_file.txt');
disp('Sixth pass - just to be sure...:');
islogicaldisp(Data.boolVar)
isdoubledisp(Data.boolVar)
clear readData2
Data = readData2('data_file.txt');
disp('7th pass - cleared readData2 function:');
islogicaldisp(Data.boolVar)
isdoubledisp(Data.boolVar)
And here is the result of the test script:
First pass:
isa(Data.boolVar,'logical') = 1
isa(Data.boolVar,'double') = 0
Second pass - converted to double!?!?:
isa(Data.boolVar,'logical') = 0
isa(Data.boolVar,'double') = 1
Third pass - just to make sure...:
isa(Data.boolVar,'logical') = 0
isa(Data.boolVar,'double') = 1
Fourth pass - this time add an inactive breakpoint:
isa(Data.boolVar,'logical') = 1
isa(Data.boolVar,'double') = 0
What?? ^^^^^^^^^
Fifth pass - deactivate breakpoint and try again:
isa(Data.boolVar,'logical') = 0
isa(Data.boolVar,'double') = 1
Sixth pass - just to be sure...:
isa(Data.boolVar,'logical') = 0
isa(Data.boolVar,'double') = 1
7th pass - cleared readData2 function:
isa(Data.boolVar,'logical') = 1
isa(Data.boolVar,'double') = 0
Any idea what is going on here?
Thanks!

Best Answer

  • Setting a breakpoint disables the JIT acceleration. This is required, because the JIT can re-order the commands to gain more speed. But re-ordered commands are not useful when the source code is debugged. Therefore it seems like you have found an inconsistency in the JIT processing.
    Try:
    feature JIT off
    feature accel off
    Then run the code again.